我想更改应用程序查找app.config文件的位置。
我知道我可以使用ConfigurationManager.OpenExeConfiguration()来访问任意配置文件 - 但是,当.Net Framework读取配置文件时(例如,对于ConnectionStrings或EventSources),它将查看默认位置。我想实际更改整个.Net Framework的位置(当然,对于我的应用程序)。
我也知道我可以使用AppDomainSetup来更改app.config的位置以用于新的AppDomain。但是,这不适用于应用程序的主AppDomain。
我也知道我可以覆盖函数Main()并创建一个新的AppDomain,并在新的AppDomain中运行我的应用程序。但是,这有其他副作用 - 例如,Assembly.GetEntryAssembly()将返回一个空引用。
考虑到.Net中的其他一切是如何工作的,我希望有一些方法来配置我的应用程序的启动环境 - 通过应用程序清单,或者其他一些 - 但我一直无法找到一线希望在那个方向。
任何指针都会有所帮助。
David Mullin
答案 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>