如何更改app.config的位置

时间:2010-09-03 01:18:12

标签: c# .net path app-config

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

我知道我可以使用ConfigurationManager.OpenExeConfiguration()来访问任意配置文件 - 但是,当.Net Framework读取配置文件时(例如,对于ConnectionStrings或EventSources),它将查看默认位置。我想实际更改整个.Net Framework的位置(当然,对于我的应用程序)。

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

我也知道我可以覆盖函数Main()并创建一个新的AppDomain,并在新的AppDomain中运行我的应用程序。但是,这有其他副作用 - 例如,Assembly.GetEntryAssembly()将返回一个空引用。

考虑到.Net中的其他一切是如何工作的,我希望有一些方法来配置我的应用程序的启动环境 - 通过应用程序清单,或者其他一些 - 但我一直无法找到一线希望在那个方向。

任何指针都会有所帮助。

David Mullin

4 个答案:

答案 0 :(得分:9)

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

GetEntryAssembly()没有问题;当从非托管代码调用时它只返回null - 或者至少它不适合我,因为我使用ExecuteAssembly()来创建/运行第二个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和不同的配置一样。另请注意,您需要有一些“魔法”选项,以防止这种情况无休止地进行。

我用更大的(真实的)代码块来制作它,所以它可能无法正常工作,但应该说明这个概念。

答案 1 :(得分:0)

我不确定您为什么要更改配置文件的位置 - 也许可以有不同的方法来解决您的实际问题。我有一个要求,我希望在相关应用程序之间共享配置文件 - 我选择使用自己的xml文件,因为它给了我完全控制架构的额外好处。

在您的情况下,可以使用configSource属性将配置文件的各个部分外部化为单独的文件。请参阅“使用外部配置文件”下的here以查看连接字符串部分的完成方式。也许,这可能对你有帮助。

答案 2 :(得分:0)

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);

然后根据需要使用config成员。

答案 3 :(得分:0)

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

如果您以只读容量使用配置文件,则可以使用XML Inlcude将相关块添加到不同位置的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>