代码之家  ›  专栏  ›  技术社区  ›  David Mullin

如何更改app.config的位置

  •  8
  • David Mullin  · 技术社区  · 14 年前

    我想更改应用程序查找app.config文件的位置。

    我知道我可以使用configurationmanager.openexeconfiguration()访问任意配置文件-但是,当.NET框架读取配置文件时(例如,对于connectionStrings或eventsources),它将查看默认位置。我想实际更改整个.NET框架的全局位置(当然,对于我的应用程序)。

    我还知道,我可以使用AppDomainSetup更改新AppDomain的app.config的位置。但是,这不适用于应用程序的主AppDomain。

    我还知道我可以重写函数main()并如上所述创建一个新的AppDomain,并在新的AppDomain中运行我的应用程序。但是,这还有其他副作用-例如,assembly.getEntryassembly()将返回空引用。

    考虑到在.NET中其他一切都是如何工作的,我希望有某种方法来配置我的应用程序的启动环境——通过应用程序清单,或者类似的方式——但是我甚至没有在这个方向上找到一丝希望。

    任何指针都是有用的。

    穆林

    4 回复  |  直到 6 年前
        1
  •  9
  •   Christian.K    14 年前

    我使用这种方法从main()启动另一个AppDomain,指定配置文件的“新”位置。

    getEntryAssembly()没有问题;当从非托管代码调用它时,它只返回空值-或者至少对我不返回空值,因为我使用executeSassembly()创建/运行第二个AppDomain,就像这样:

    int Main(string[] args)
    {
       string currentExecutable = Assembly.GetExecutingAssembly().Location;
    
       bool inChild = false;
       List<string> xargs = new List<string>();
       foreach (string arg in xargs)
       {
          if (arg.Equals("-child"))
          {
             inChild = true;
          }
          /* Parse other command line arguments */
          else
          {
             xargs.Add(arg);
          }
       }
    
       if (!inChild)
       {
          AppDomainSetup info = new AppDomainSetup();
          info.ConfigurationFile = /* Path to desired App.Config File */;
          Evidence evidence = AppDomain.CurrentDomain.Evidence;
          AppDomain domain = AppDomain.CreateDomain(friendlyName, evidence, info);
    
          xargs.Add("-child"); // Prevent recursion
    
          return domain.ExecuteAssembly(currentExecutable, evidence, xargs.ToArray());
       }
    
       // Execute actual Main-Code, we are in the child domain with the custom app.config
    
       return 0;
    }
    

    注意,我们正在有效地重新运行exe,就像一个AppDomain和一个不同的配置一样。另外请注意,您需要有一些“魔法”选项来阻止这种情况不断发生。

    我是从更大的(真实的)代码块中创建的,因此它可能不会按原样工作,但应该说明这个概念。

        2
  •  0
  •   VinayC    14 年前

    我不知道您为什么要更改配置文件的位置-也许有不同的方法来解决您的实际问题。我有一个要求,我想在相关的应用程序之间共享配置文件——我选择使用自己的XML文件,因为它给了我完全控制模式的额外好处。

    在您的情况下,可以使用configSource属性将配置文件的各个部分外部化为单独的文件。见 here 在“使用外部配置文件”下,检查如何为连接字符串部分执行此操作。也许,这对你有帮助。

        3
  •  0
  •   Berezh    12 年前
    var configPath = YOUR_PATH;
    if (!Directory.Exists(ProductFolder))
    {
        Directory.CreateDirectory(ProductFolder);
    }
    
    if (!File.Exists(configPath))
    {
        File.WriteAllText(configPath, Resources.App);
    }
    
    var map = new ExeConfigurationFileMap
    {
        ExeConfigFilename = configPath,
        LocalUserConfigFilename = configPath,
        RoamingUserConfigFilename = configPath
    };
    
    Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
    

    然后根据需要使用配置成员。

        4
  •  0
  •   VoteCoffee    6 年前

    另一种方法是将配置文件保留在可执行文件中,并将相关的可更改部分移动到外部XML文件中,该文件可以位于您选择的任何位置。

    如果您使用的配置文件是只读的,那么您可以使用XML inlude将相关的块添加到其他位置的XML文件中。如果您试图使用configuration.save方法将值直接写回app.config,则此操作将不起作用。

    App.CONFIG:

    <?xml version="1.0"?>
    <configuration xmlns:xi="http://www.w3.org/2001/XInclude">
        <appSettings>
          <xi:include href="AppSettings.xml"/>
        </appSettings>
      <connectionStrings>
        <xi:include href="ConnectionStrings.xml"/>
      </connectionStrings>
    <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/></startup>
    </configuration>

    connectionStrings.xml:

    <?xml version="1.0"?>
    <add name="Example1ConnectionString"
            connectionString="Data Source=(local)\SQLExpress;Initial Catalog=Example1DB;Persist Security Info=True;User ID=sa;Password=password"
            providerName="System.Data.SqlClient" />
    <add name="Example2ConnectionString"
            connectionString="Data Source=(local)\SQLExpress;Initial Catalog=Example2DB;Persist Security Info=True;User ID=sa;Password=password"
            providerName="System.Data.SqlClient" />

    appsettings.xml文件:

    <?xml version="1.0"?>
    <add key="Setting1" value="Value1"/>
    <add key="Setting2" value="Value2"/>

    文件URI如下所示:

    file:///C:/whatever.txt
    

    您甚至可以定义故障转移文件,以防您试图引用的文件丢失。这个图案是从 https://www.xml.com/pub/a/2002/07/31/xinclude.html :

    <xi:include href="http://www.whitehouse.gov/malapropisms.xml">
      <xi:fallback>
        <para>
          This administration is doing everything we can to end the stalemate in
          an efficient way. We're making the right decisions to bring the solution
          to an end.
        </para>
      </xi:fallback>