3

我有一个使用 Visual Studio 2008 的发布 (ClickOnce) 系统部署的 WinForms 应用程序。在应用程序的app.config文件中,我有一个第三方组件所需的配置部分,其形式为:

<section name="thirdPartySection"
type="System.Configuration.NameValueSectionHandler" />

因此,该部分不在 appSettings 中,如下所示:

<thirdPartySection >
  <add key="someKey" value="someValue" />
</thirdPartySection >

我了解键/值对是 NameValueCollection。我面临的问题是我希望在部署时间或运行时更改someValue值(对我来说都可以),以便someOtherValue基于安装的环境。

目前我在运行时进行了一些其他配置更改,但这些都在该AppSettings部分中,因此很容易获得。我在寻找解决方案时发现了许多参考资料,但它们似乎依赖于具有自定义类的部分,而不是我面临的 NameValueCollection。

有谁知道修改此数据的最佳方法?使用 ConfigurationManager.RefreshSection() 进行运行时更改将更符合我当前的代码,但我也愿意在安装阶段接受建议。

编辑:这在运行时有效。这就是我处理旧配置覆盖的方式。

Configuration config = ConfigurationManager.OpenExeConfiguration(
    ConfigurationUserLevel.None);

config.AppSettings.Settings["Main.ConnectionString"].Value = 
    PolicyTrackerInfo.ConnectionString;

config.AppSettings.Settings["Main.linq"].Value = 
    PolicyTrackerInfo.LinqConnectionString;


config.Save(ConfigurationSaveMode.Modified);

ConfigurationManager.RefreshSection("appSettings");

我尝试对另一个部分做同样的事情:

string overwriteXml = config.GetSection("thirdPartySection")
    .SectionInformation.GetRawXml();

XmlDocument xml = new XmlDocument();
xml.LoadXml(overwriteXml);
XmlNode node = xml.SelectSingleNode("thirdPartySection/add");
node.Attributes["value"].Value = PolicyTrackerInfo.OverwriteString;

到现在为止还挺好。但是,我没有看到允许我用修改后的数据替换旧 XML 的方法。在运行时可以吗?

顺便说一句:我尝试手动修改 app.config.deploy 文件。这只是给我一个验证错误,因为安装程序检测到修改并且它拒绝继续。我真的很喜欢自动部署,并且之前的覆盖效果很好。

4

3 回答 3

1

为了提出人们可以投票赞成或反对的想法(除了风滚草,我在这个问题上看到的不多),我正在考虑使用此处发布的技术:http: //www.devx.com /dotnet/文章/10045

基本思想是让 ClickOnce 部署一个 shim 应用程序,该应用程序只会对主应用程序进行 XCOPY 部署(由于它不使用 app.config 文件,我可以使用标准的 XML 修改技术并完成它)。

或者,由于此应用程序是从网络部署的,我可能只是将程序集放在网络上并使用权限系统授予它访问所需文件夹和数据库的权限。有什么想法吗?

于 2010-02-05T20:56:34.080 回答
1

您可以做的一件事是在您的代码中添加一个首次运行部分来进行额外设置,例如修改应用程序配置文件。要检测是否需要完成此设置,您的第三方配置部分可能会预先填充您的应用程序将识别为属于新安装的虚拟值。例如,您的配置文件可能如下所示:

<thirdPartySection>
    <add key="someKey" value="#NEEDS_INITIALIZED#" />
</thirdPartySection >

您的Main方法可能如下所示:

static public void Main(params string[] args)
{
    const string uninitializedValue = "#NEEDS_INITIALIZED#";

    // Load the third-party config section (this assumes it inherits from
    // ConfigurationElementCollection
    var config = ConfigurationManager.OpenExeConfiguration(
        ConfigurationUserLevel.None);
    var section = config.GetSection("thirdPartySection") 
        as NameValueConfigurationCollection;
    var setting = section["someKey"];
    if (setting.Value == uninitializedValue)
    {
        setting.Value = PolicyTrackerInfo.OverwriteString;
        config.Save();
    }
}
于 2010-02-06T19:38:47.960 回答
0

我会编写一个自定义安装程序,并在 AfterInstall 事件中使用上面的 XML 机制修改配置文件。不过,我不知道 ClickOnce 如何或是否有效。

于 2010-02-05T18:23:26.330 回答