从自定义安装程序类操作更新<appname> .config文件

bla*_*k3r 5 .net c# windows-installer

我在安装过程中尝试更新我的应用程序的.config文件(通过.NET安装程序类操作).但是,我似乎无法让ConfigurationManager列出任何属性或能够设置任何东西.

我从几个stackoverflow帖子中了解了这种方法,这些帖子向我指出了本指南:http://raquila.com/software/configure-app-config-application-settings-during-msi-install/

我已经调查了我的项目和他之间的差异,并注意到我的配置文件格式不同.我相信这与我正在使用"设置"文件的事实有关.

在指南中格式化的配置文件如下所示:

<?xml version="1.0" encoding="utf-8" ?>     
<configuration>     
  <appSettings>      
    <add key="Param1" value="" />      
    <add key="Param2" value="" />      
    <add key="Param3" value="" />      
  </appSettings>      
</configuration> 
Run Code Online (Sandbox Code Playgroud)

我的地方看起来像:

   <?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="MyAppName.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
            <section name="MyAppName.Settings1" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="MyAppName.Settings1" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <userSettings>
        <MyAppName.Properties.Settings>
            <setting name="TESTSETTING" serializeAs="String">
                <value>asdfasdfasdf</value>
            </setting>
        </MyAppName.Properties.Settings>
        <MyAppName.Settings1>
            <setting name="VerboseErrorMode" serializeAs="String">
                <value>False</value>
            </setting>
    <applicationSettings>
        <MyAppName.Settings1>
            <setting name="RunOnStartup" serializeAs="String">
                <value>True</value>
            </setting>
        </MyAppName.Settings1>
    </applicationSettings>
</configuration>
Run Code Online (Sandbox Code Playgroud)

为了解释发生了什么......我尝试打印出如下所示的设置列表:

            Configuration config = ConfigurationManager.OpenExeConfiguration(exePath);               

            // Try getting the Settings1 Section
            AppSettingsSection appSettings = (AppSettingsSection)config.GetSection("Settings1");  // Also tried myNamespace.Settings1
            if (appSettings != null)
            {
                valList = "Settings1: ";
                foreach (string key in appSettings.Settings.AllKeys)
                {
                    string value = appSettings.Settings[key].Value;
                    valList += ("Key: '" + key + "' = '" + value + "'\n");
                }
            }
            else
            {
                valList = "appSettings was null";
            }
            MessageBox.Show(valList);

        MessageBox.Show(valList);
Run Code Online (Sandbox Code Playgroud)

我尝试了几种这种排列......在所有情况下输出都是"appSettings为null".

我也试过用几种不同的方式初始化配置管理器......

            Configuration config = ConfigurationManager.OpenExeConfiguration(exePath);

            MessageBox.Show("Section Count: " + config.Sections.Count);
            MessageBox.Show("Has File: " + config.HasFile);
            MessageBox.Show("Namespace Declared: " + config.NamespaceDeclared);

            config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            MessageBox.Show("Section Count: " + config.Sections.Count);
            MessageBox.Show("Has File: " + config.HasFile);
            MessageBox.Show("Namespace Declared: " + config.NamespaceDeclared);
Run Code Online (Sandbox Code Playgroud)

对于他们每个人,返回的部分计数是20.(我不知道20来自哪里......我原以为它是3).
HasFile对于第一种情况是正确的而对于第二种情况则是错误的.
在两种情况下,Namespace声明都是false.

谢谢!

编辑(6-18-09):仍在调查这个问题.其他人有什么想法吗?谢谢.

搜索关键字:"对象引用未设置为未设置为实例"< - 尝试写入属性时会发生这种情况.

K.A*_*.D. 11

我遇到了同样的问题,经过深入调查,我找到了更新配置文件的任何部分(例如app.config)的最简单方法,即使用XPath.我们有一个连接到Web服务的应用程序,在安装过程中,用户输入Web服务的URL,这应该保存在以下app.config文件中:

        <?xml version="1.0"?>
    <configuration>
      <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
          <section name="ApplicationServer.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
      </configSections>

      <applicationSettings>
        <ApplicationServer.Properties.Settings>
          <setting name="ApplicationServer_ApplicationServerUrl" serializeAs="String">
            <value>whatever comes from setup should go here</value>
          </setting>
        </ApplicationServer.Properties.Settings>
      </applicationSettings>
    </configuration>
Run Code Online (Sandbox Code Playgroud)

以下是在安装程序类中执行此操作的代码:

public override void Install(System.Collections.IDictionary stateSaver)
    {
        base.Install(stateSaver);

        string targetDirectory = Context.Parameters["targetdir"];
        string param1 = Context.Parameters["param1"];

        string path = System.IO.Path.Combine(targetDirectory, "app.config");

        System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();

        xDoc.Load(path);

        System.Xml.XmlNode node = xDoc.SelectSingleNode("/configuration/applicationSettings/Intellisense.ApplicationServer.Properties.Settings/setting[@name='ApplicationServer_ApplicationServerUrl']/value");
        node.InnerText = (param1.EndsWith("/") ? param1 : param1 + "/");

        xDoc.Save(path); // saves the web.config file  
    }
Run Code Online (Sandbox Code Playgroud)

基本上,由于配置文件是基于XML的文档,我使用XPath表达式来定位特定节点并更改其值.