2015-10-20 77 views
0

我創建了一個命令行應用程序,並將其許多配置移動到標準設置文件中。所有設置都被聲明爲Scope = Application,因爲沒有關於應用程序邏輯的特定用戶。我訪問值在整個代碼app.config - 如何在運行時強制從文件加載?

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> 
... 

我還要提到的是我也試過「的applicationSettings '代替上述代碼中的'appSettings'。

+1

'ConfigurationManager.RefreshSection(「appSettings」)'適用於我。你確定app.config真的更新了嗎? – Alexander

+0

「Properties.Settings」中的用戶設置與輸出文件夾中的'.config'文件不應有任何關係,它們存儲在用戶的本地應用程序數據文件夾中。 – Groo

+0

GUI.exe將讀取GUI.exe.config而不是cli.exe.config - 就這麼簡單。 –

回答

0

確保訪問修飾符已被設置爲公共。使用'GetExecutingAssembly'啓動將不會加載CLI配置,如果它已被GUI.EXE觸發,因爲這是正在執行的程序集。看看這個:

Accessing app config across exe's

+0

將修改器更改爲Public並沒有做任何我害怕的事情。 – Gargravarr

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應用程序數據文件夾複製到新入口點的相應文件夾。

(更新應用程序設置)

它爲應用程序設置(即.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> 

(這是可能的我在寫這篇文章時混淆了一些值,但你明白了)。

我還發現一個搜索工具:XmlConfigMerge on CodeProject - 我還沒有嘗試過,但可能它會自動執行相同的操作,因此您可能需要檢查並將其包含到構建腳本中。

+0

順便說一句,我沒有使用.NET應用程序設置的原因很多(比如你發現的那個,或者發佈新應用程序版本時的版本/升級問題)。例如,我們公司的Settings類,根據dll程序集名稱將設置加載並存儲到應用程序數據文件夾/文件,以便每個程序集都有自己的配置文件。**但是**,說了這樣的話,有些情況下你希望每個入口點對同一個程序集有不同的設置,而對於.NET設置,你爲每個入口點獲得一個新的'user.config'文件(包含所有引用程序集的設置)。 – Groo

+0

我檢查了AppData文件夾,並且沒有任何應用程序的本地設置;正如我所指出的,所有設置都是應用程序範圍,而不是用戶範圍,所以不需要創建它們。你說可執行文件旁邊的Settings文件應該提供默認值 - 這正是我想要的用途,因爲這些值在運行時不會改變,但應該事先更改。但是,這沒有發生。 – Gargravarr

+0

@Gargravarr:它與應用程序設置一樣,只需要將設置合併到入口點的'.config'文件中即可。 .NET應用程序設置背後的想法是允許每個入口點都有一組單獨的配置設置。檢查我的編輯。 – Groo