Как вы записываете чистую версию вашей конфигурации при первом запуске программы?

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

Это оказалось удивительно сложно!

Вот что мне нужно было сделать:

  • получить путь к конфигу
  • сохранить пустой конфиг с заглушками для соответствующих свойств

Инструмент был выпущен с использованием CC.net и MSI создан с использованием wix. К сожалению это было актуально!

2 ответа

Решение

Получить путь к конфигу

Этот бит оказался очень простым:

вы просто используете что-то вроде этого:

    public string FileLocation
    {
        get { return Configuration.FilePath; }
    }

    private static Configuration Configuration
    {
        get { return OpenConfig(ConfigurationUserLevel.PerUserRoamingAndLocal); }
    }

    private static Configuration OpenConfig(ConfigurationUserLevel userLevel)
    {
        return ConfigurationManager.OpenExeConfiguration(userLevel);
    }

Существует два других значения для перечисления: ни одно из них не указывает на то, где должен быть app.config, а PerUserRoaming всегда указывает на то, что не существует. Я не смог узнать больше подробностей о том, когда это может быть целесообразно использовать, но в моем случае это не так.

Как уже упоминалось выше, одна из запутанных вещей в этом вызове заключается в том, что он вернет путь к файлу, если он будет сохранен / существует. Это означает, что часто этот файл не существует! Неясные отношения между ConfigurationManager и Settings (автоматически сгенерированный класс, полученный из ApplicationSettingsBase) - вот что доставило мне много боли!

сохранить пустой конфиг

Несколько камней преткновения были следующими:

если вы добавите класс settings.Settings, он также добавит app.config. Если вы не отправите это вместе с установленной программой, то вы увидите различное поведение между установленной версией программы и версией dev - один будет создавать файлы настроек, используя значения из app.config, а другой - нет. Самым простым решением для меня было полное удаление app.config.

Я пытался использовать метод сохранения в конфигурации, который позволяет указать, что вы сохраняете все свойства (независимо от значения по умолчанию), и позволяет указать сохранение, даже если конфигурация не была изменена. Однако вызов этого метода с обоими установленными флагами ничего не изменит - похоже, что настройки, созданные вами в конструкторе, каким-то образом не являются реальными до тех пор, пока они не будут установлены - Configuration и ConfigurationManager являются более старым способом выполнения действий, а ApplicationSettingsBase, вероятно, использует один или оба из них они плохо интегрируются.

Чтобы сделать это более запутанным, если вы запрашиваете настройки, у них будут значения (для строк у них будет ""). Однако если вы сохраните настройки, то эти настройки не будут сохранены в месте, указанном в файле! На самом деле ни один файл не будет создан вообще! Хотя, если у вас есть app.config, файл будет создан, если вы используете метод принудительного сохранения выше, так как значения по умолчанию указаны в app.config!

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

        var somethingUnSet = _settings.Something == "";
        if (somethingUnset)
            _settings.Something = "";

        if(somethingUnset|| somethingElseUnset)
        {
            _settings.Save();
            ExitWithError("config needs setting up at " + _settings.FileLocation);
            return;
        }  

Наконец, это дало мне желаемый результат - файл сохраняется в месте, указанном менеджером конфигурации, с пустыми свойствами, которые необходимо заполнить. Думаю, пользовательский интерфейс был бы быстрее!!!

Я использовал обернутый объект "Настройки", чтобы облегчить изменение значений в тестах, не имея дело с одноэлементным. Это также имеет приятный побочный эффект: вы можете использовать дополнительный код (например, расположение файла), и вам не придется беспокоиться о перезаписи кода, когда вы добавляете больше настроек.

Просто установите все элементы в файле.config на ничего при первом запуске, как:

ConfigurationManager.appSettings["item1"] = ""; 

и проверьте значение.

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

Другие вопросы по тегам