代码之家  ›  专栏  ›  技术社区  ›  Godeke

在运行时或安装时修改app.config中的配置节

  •  3
  • Godeke  · 技术社区  · 15 年前

    我有一个使用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文件。这只会给我一个验证错误,因为安装程序检测到修改,它拒绝继续。我真的很喜欢自动部署,以前的覆盖工作得很好。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Jacob    15 年前

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

    <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();
        }
    }
    
        2
  •  1
  •   Godeke    15 年前

    为了提出这样一个观点,即人们可以投票赞成或反对(不是说我在这个问题上看到了除风滚草以外的很多东西),我正在考虑使用这里发布的技术: http://www.devx.com/dotnet/Article/10045

    基本思想是让ClickOnce部署一个填充程序应用程序,它只对主应用程序进行xcopy部署(因为它不使用app.config文件,所以我可以使用标准的XML修改技术并完成它)。

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

        3
  •  0
  •   Jacob G    15 年前

    我会写一篇 custom installer 并且,在AfterInstall事件中,使用上面的XML机制修改配置文件。不过,我不知道ClickOnce是如何工作的,或者是否可以工作的。

    推荐文章