app.config - 如何在运行时强制从文件加载?

时间:2015-10-20 11:02:47

标签: c# .net xml app-config

我创建了一个命令行应用程序,并将其大量配置移动到标准设置文件中。所有设置都声明为Scope = Application,因为应用程序中没有任何特定于用户的逻辑。我使用

访问整个代码中的值
Properties.Settings.Default.<whatever>  

这很好用,因为它按计划自动运行。更新配置文件中的值将反映在输出中 一段时间后,我创建了一个基本的GUI(在同一名称空间中)直接启动命令行应用程序(通过单独的构造函数)。我还没有完成大量的.Net编程,但我基本上都在使用我的CLI应用程序,比如DLL(我不知道是否有适当的术语;在我的输出文件夹,我需要的是GUI.exe,CLI.exe和CLI.exe.config,它的工作原理)。但是,我注意到以这种方式启动时,未加载CLI.exe.config文件; CLI应用程序仅使用其已编译的默认值。我希望配置文件方法在这个例子中起作用 我已经尝试了以下方法来强制加载配置文件,但到目前为止已经画了一个空白:

1

ConfigurationManager.RefreshSection("appSettings")  

2:

ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
configFile.ExeConfigFilename = Path.Combine(Environment.CurrentDirectory, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".exe.config");
ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None).Save(ConfigurationSaveMod.Modified);  
ConfigurationManager.RefreshSection("appSettings");  

3:

Properties.Settings.Default.Reload();  

这些都不会产生错误,但我在配置文件中修改的Properties.Settings.Default.Value未更新。有没有办法在这里完成我需要的东西?

编辑:这是我的CLI.exe.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="CLI.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    </sectionGroup>
  </configSections>
  <connectionStrings/>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <applicationSettings>
    <CLI.Properties.Settings>
      <setting name="URLBase" serializeAs="String">
        <value>https://cloud.mycompany.com/</value>
      </setting>
      <setting name="URLPage" serializeAs="String">
        <value>/inventory.aspx#view/Invoice/</value> <!-- This is the value I'm trying to change -->
      </setting>
...

我还应该提一下,我也尝试过“应用设置”。代替&#39; appSettings&#39;在上面的代码中。

2 个答案:

答案 0 :(得分:0)

确保访问修饰符已设置为公共。如果由GUI.EXE触发,则使用'GetExecutingAssembly'启动将不会加载CLI配置,因为这是执行程序集。看看这个:

Accessing app config across exe's

答案 1 :(得分:0)

具有运行时设置的实际config文件将取决于您的应用程序的入口点。

如果您直接启动CLI.exe,它将在用户的本地应用数据文件夹内的子文件夹中使用用户设置文件,类似于:

AppData\Local\CLI\CLI.exe\1.2.3.4\user.config

但是,如果您使用引用CLI.exe的其他入口点(GUI.exe),则对Properties.Settings的所有调用都将使用完全不同的user.config实例,位于(像这样):

AppData\Local\GUI\GUI.exe\1.2.3.4\user.config

应用程序范围的设置文件(.exe.config)位于可执行文件旁边的输出文件夹中,仅为这些用户设置或只读应用程序设置提供默认设置 。允许应用程序写入此文件意味着它将具有对Program Files子文件夹的写入权限,如果没有提升权限,则无法进行写入访问。

更改入口点时获取相同用户设置的最简单方法是将user.config文件从CLI app数据文件夹复制到新入口点的相应文件夹中。

(针对应用设置进行更新)

它对于应用程序设置(即输出文件夹中的.config文件)的工作方式相同。如果你原来有:

<!-- CLI.exe.config -->
<configuration>

    <!-- setting section definitions -->
    <configSections>
        <sectionGroup name="userSettings" ... >
            <section name="CLI.CliSettings" ... />
        </sectionGroup>
        <sectionGroup name="applicationSettings" ... >
            <section name="CLI.CliSettings" ... />
        </sectionGroup>
    </configSections>

    <!-- defaults for user settings (runtime changes are stored to appdata) -->
    <userSettings>
        <CLI.CliSettings>
            <setting name="SomeUserCliSetting" serializeAs="String">
                <value>Some CLI user setting</value>
            </setting>
        </CLI.CliSettings>
    </userSettings>

    <!-- application settings (readonly) -->
    <applicationSettings>
        <CLI.CliSettings>
            <setting name="SomeAppCliSetting" serializeAs="String">
                <value>Some CLI app setting</value>
            </setting>
        </CLI.CliSettings>
    </applicationSettings>

</configuration>

你的GUI.exe.config是:

<!-- GUI.exe.config -->
<configuration>

    <configSections>
        <sectionGroup name="userSettings" ... >
            <section name="GUI.GuiSettings" ... />
        </sectionGroup>
        <sectionGroup name="applicationSettings" ... >
            <section name="GUI.GuiSettings" ... />
        </sectionGroup>
    </configSections>

    <userSettings>
        <GUI.GuiSettings>
            <setting name="SomeGuiUserSetting" serializeAs="String">
                <value>Some GUI user setting</value>
            </setting>
        </GUI.GuiSettings>
    </userSettings>

    <applicationSettings>
        <GUI.GuiSettings>
            <setting name="SomeGuiAppSetting" serializeAs="String">
                <value>Some GUI app setting</value>
            </setting>
        </GUI.GuiSettings>
    </applicationSettings>

</configuration>

然后,生成的.config文件应包含所有部分:

<!-- GUI.exe.config -- merged configuration sections -->
<configuration>

    <configSections>
        <sectionGroup name="userSettings" ... >
            <section name="GUI.GuiSettings" ... />
            <section name="CLI.CliSettings" ... />
        </sectionGroup>
        <sectionGroup name="applicationSettings" ... >
            <section name="GUI.GuiSettings" ... />
            <section name="CLI.CliSettings" ... />
        </sectionGroup>
    </configSections>

    <userSettings>
        <GUI.GuiSettings>
            <setting name="SomeGuiUserSetting" serializeAs="String">
                <value>Some GUI user setting</value>
            </setting>
        </GUI.GuiSettings>
        <CLI.CliSettings>
            <setting name="SomeUserCliSetting" serializeAs="String">
                <value>Some CLI user setting</value>
            </setting>
        </CLI.CliSettings>
    </userSettings>

    <applicationSettings>
        <GUI.GuiSettings>
            <setting name="SomeGuiAppSetting" serializeAs="String">
                <value>Some gui app setting</value>
            </setting>
        </GUI.GuiSettings>
        <CLI.CliSettings>
            <setting name="SomeAppCliSetting" serializeAs="String">
                <value>Some CLI app setting</value>
            </setting>
        </CLI.CliSettings>
    </applicationSettings>

</configuration>

(在写这篇文章时我可能会混淆一些值,但你明白了。)

我还通过Google搜索找到了一个工具:XmlConfigMerge on CodeProject - 我还没有尝试过,但可能会自动执行相同的操作,因此您可能需要查看它并将其包含在您的构建中脚本。