繁体   English   中英

如何更改app.config的位置

[英]How to change location of app.config

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

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

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

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

鉴于.Net中其他所有工作方式,我希望有一些方法来配置我的应用程序的启动环境 - 通过应用程序清单,或者其他一些 - 但我一直无法在这个方向找到一线希望。

任何指针都会有所帮助。

大卫穆林

我使用该方法从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和不同的配置一样。 另请注意,您需要有一些“魔法”选项,以防止这种情况无休止地进行。

我从一个更大的(真实的)代码块中精心设计出来,所以它可能无法正常工作,但应该说明这个概念。

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成员。

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

在您的情况下,可以使用configSource属性将配置文件的各个部分外部化为单独的文件。 这里下的“使用外部配置文件”,以检查它如何被用于连接字符串部分完成。 也许,这可能会对你有所帮助。

另一种方法是将配置文件保留为可执行文件,并将相关的可更改部分移动到外部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> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM