Изменение разделов конфигурации в App.config во время выполнения или установки - PullRequest
3 голосов
/ 22 января 2010

У меня есть приложение WinForms, которое развернуто с помощью системы публикации (ClickOnce) Visual Studio 2008. В файле app.config приложения есть раздел конфигурации, который требуется стороннему компоненту в форме:

<section name="thirdPartySection"
type="System.Configuration.NameValueSectionHandler" />

Раздел, таким образом, отсутствует в appSettings и выглядит так:

<thirdPartySection >
  <add key="someKey" value="someValue" />
</thirdPartySection >

Я понимаю, что пары ключ / значение являются NameValueCollection. Проблема, с которой я сталкиваюсь, заключается в том, что я хочу изменить значение либо во время развертывания, либо во время выполнения (либо мне подходит), так что someValue будет someOtherValue в зависимости от установленной среды.

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

Кто-нибудь знает лучший способ изменить эти данные? Изменение времени выполнения с помощью ConfigurationManager.RefreshSection () будет в большей степени соответствовать моему текущему коду, но я открыт для предложений и на этапе установки.

Редактировать: Это работает во время выполнения. Так я обрабатывал старые переопределения конфигурации.

Configuration config = ConfigurationManager.OpenExeConfiguration(
    ConfigurationUserLevel.None);

config.AppSettings.Settings["Main.ConnectionString"].Value = 
    PolicyTrackerInfo.ConnectionString;

config.AppSettings.Settings["Main.linq"].Value = 
    PolicyTrackerInfo.LinqConnectionString;


config.Save(ConfigurationSaveMode.Modified);

ConfigurationManager.RefreshSection("appSettings");

Моя попытка сделать то же самое для другого раздела:

string overwriteXml = config.GetSection("thirdPartySection")
    .SectionInformation.GetRawXml();

XmlDocument xml = new XmlDocument();
xml.LoadXml(overwriteXml);
XmlNode node = xml.SelectSingleNode("thirdPartySection/add");
node.Attributes["value"].Value = PolicyTrackerInfo.OverwriteString;

Пока все хорошо. Однако я не вижу метода, который позволил бы мне заменить старый XML моими измененными данными. Возможно ли это во время выполнения?

В качестве отступления: я попытался вручную изменить файл app.config.deploy. Это просто дает мне ошибку проверки, так как установщик обнаруживает изменение и отказывается продолжить. Мне действительно нравится автоматическое развертывание, и предыдущее переопределение работало отлично.

Ответы [ 3 ]

1 голос
/ 05 февраля 2010

Чтобы выдвинуть идею о том, что люди могут голосовать за или против (не то, чтобы я видел что-то иное, кроме поворотов вокруг этого вопроса), я думаю об использовании техники, размещенной здесь: http://www.devx.com/dotnet/Article/10045

Основная идея состоит в том, чтобы заставить ClickOnce развертывать приложение-оболочку, которое будет просто выполнять развертывание основного приложения в XCOPY (и поскольку оно не использует файл app.config, я могу просто использовать стандартные методы модификации XML и работать с это).

В качестве альтернативы, поскольку это приложение развернуто из сети, я могу просто поместить сборку в сеть и поработать с системой разрешений, чтобы предоставить ей доступ к нужным папкам и базе данных. Какие-нибудь мысли?

1 голос
/ 06 февраля 2010

Одна вещь, которую вы можете сделать, это добавить в ваш код впервые запускаемый раздел, который выполняет дополнительные настройки, такие как изменение файла конфигурации приложения. Чтобы определить, нужно ли выполнить эту настройку, ваш сторонний раздел конфигурации может быть предварительно заполнен фиктивными значениями, которые ваше приложение распознает как принадлежащие новой установке. Например, ваш файл конфигурации может выглядеть так:

<thirdPartySection>
    <add key="someKey" value="#NEEDS_INITIALIZED#" />
</thirdPartySection >

И ваш Main метод может выглядеть примерно так:

static public void Main(params string[] args)
{
    const string uninitializedValue = "#NEEDS_INITIALIZED#";

    // Load the third-party config section (this assumes it inherits from
    // ConfigurationElementCollection
    var config = ConfigurationManager.OpenExeConfiguration(
        ConfigurationUserLevel.None);
    var section = config.GetSection("thirdPartySection") 
        as NameValueConfigurationCollection;
    var setting = section["someKey"];
    if (setting.Value == uninitializedValue)
    {
        setting.Value = PolicyTrackerInfo.OverwriteString;
        config.Save();
    }
}
0 голосов
/ 05 февраля 2010

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

...