Как изменить местоположение app.config - PullRequest
8 голосов
/ 03 сентября 2010

Я хочу изменить местоположение, где мое приложение ищет файл app.config.

Я знаю, что могу использовать ConfigurationManager.OpenExeConfiguration () для доступа к произвольному файлу конфигурации - однако, когда .Net Framework читает файл конфигурации (например, для ConnectionStrings или EventSources), он будет искать расположение по умолчанию. Я хочу изменить местоположение в целом для всей .Net Framework (для моего приложения, конечно).

Я также знаю, что могу использовать AppDomainSetup, чтобы изменить местоположение app.config для нового AppDomain. Однако это не относится к основному домену приложения приложения.

Я также знаю, что могу переопределить функцию Main () и создать новый домен приложений, как указано выше, и запустить свое приложение в этом новом домене приложений. Однако у этого есть другие побочные эффекты - например, Assembly.GetEntryAssembly () вернет нулевую ссылку.

Учитывая то, как все остальное работает в .Net, я ожидал, что будет какой-то способ настройки среды запуска моего приложения - через манифест приложения или что-то подобное - но я не смог найти даже проблеск надежды в этом направлении.

Любой указатель будет полезен.

Дэвид Маллин

Ответы [ 4 ]

9 голосов
/ 03 сентября 2010

Я использовал подход с запуском другого AppDomain из Main (), указав «новое» расположение файла конфигурации.

Нет проблем с GetEntryAssembly ();он возвращает только ноль при вызове из неуправляемого кода - или, по крайней мере, не для меня, так как я использую 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 и с другим конфигом.Также обратите внимание, что вам нужно иметь некоторую «волшебную» опцию, которая не позволяет этому продолжаться бесконечно.

Я сделал это из большего (реального) куска кода, поэтому он может не работать как есть, но долженпроиллюстрировать концепцию.

0 голосов
/ 20 апреля 2018

Другой подход заключается в том, чтобы оставить конфигурационный файл с исполняемым файлом и переместить соответствующие изменяемые разделы во внешние XML-файлы, которые могут находиться в любом месте по вашему выбору.

Если вы используете свой конфигурационный файл только для чтенияемкости, то вы можете добавить соответствующие куски в файл XML в другом месте, используя XML Inlcude.Это не будет работать, если вы пытаетесь записать значения обратно непосредственно в app.config с помощью метода Configuration.Save.

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>
0 голосов
/ 26 марта 2013
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);

Затем используйте элемент конфигурации как хотите.

0 голосов
/ 03 сентября 2010

Я не уверен, почему вы хотите изменить местоположение вашего конфигурационного файла - возможно, может быть другой подход к решению вашей актуальной проблемы. У меня было требование, когда я хотел поделиться файлом конфигурации между смежными приложениями - я решил использовать собственный XML-файл, поскольку это дало мне дополнительное преимущество полного контроля над схемой.

В вашем случае вы можете перенести разделы вашего конфигурационного файла в отдельный файл, используя свойство configSource. См. здесь в разделе «Использование внешних файлов конфигурации», чтобы проверить, как это было сделано для раздела строк подключения. Возможно, это может вам помочь.

...