Как вы сохраняете настройки user.config в разных версиях сборки в .net?

В основном проблема заключается в том, что каждый раз, когда изменяется версия сборки (то есть пользователь устанавливает новую версию приложения), все их настройки: reset значения по умолчанию (или, точнее, новый файл user.config создается в папка с другим номером версии как имя)

Как сохранить одинаковые настройки при обновлении версий, поскольку использование ini файлов или реестра кажется обескураженным?

Когда мы использовали Clickonce, он, казалось, мог справиться с этим, поэтому кажется, что он должен быть выполнен, но я не уверен, как это сделать.

Ответ 1

ApplicationSettingsBase имеет метод под названием Upgrade, который переносит все настройки из предыдущей версии.

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

Затем при запуске приложения вы проверяете, установлен ли флаг и если он есть, вызовите Способ обновления, установите флаг в false и сохраните конфигурацию.

if (Settings.Default.UpgradeRequired)
{
    Settings.Default.Upgrade();
    Settings.Default.UpgradeRequired = false;
    Settings.Default.Save();
}

Подробнее о методе Upgrade читайте MSDN. GetPreviousVersion также может быть полезен, если вам нужно выполнить какое-то пользовательское слияние.

Ответ 2

Я знаю, что прошло некоторое время... В приложении winforms просто вызовите My.Settings.Upgrade(), прежде чем загружать их. Это позволит получить последние настройки, будь то текущая версия или предыдущая версия.

Ответ 3

Если ваши изменения в user.settings выполняются программно, как насчет сохранения копии (просто) изменений в user.settings в отдельном файле, например. user.customized.settings?

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

EDIT: я слишком быстро прочитал "более точную" часть о версиях сборки, в результате чего новый пользовательский набор настроек будет установлен в новый каталог, зависящий от версии. Таким образом, вышеприведенная идея, вероятно, не поможет вам, но может дать некоторую пищу для размышлений.

Ответ 4

Вот как я справился с этим:

public virtual void LoadSettings(ServiceFileFormBaseSettings settings = null, bool resetSettingsToDefaults = false)
{
    if (settings == null)
            return;

    if (resetSettingsToDefaults)
        settings.Reset();
    else
    {
        settings.Reload();

        if (settings.IsDefault)
            settings.Upgrade();
    }

    this.Size = settings.FormSize;

}

и в классе настроек я определил свойство IsDefault:

// SaveSettings always sets this to be FALSE.
// This will have the default value TRUE when first deployed, or immediately after an upgrade.
// When the settings exist, this is false.
//
[UserScopedSettingAttribute()]
[DefaultSettingValueAttribute("true")]
public virtual bool IsDefault
{
    get { return (bool)this["IsDefault"]; }
    set { this["IsDefault"] = value; }
}

В SaveSettings я установил IsDefault в false:

public virtual void SaveSettings(ServiceFileFormBaseSettings settings = null)
{
    if (settings == null) // ignore calls from this base form, if any
        return;

    settings.IsDefault = false;
    settings.FormSize = this.Size;
    settings.Save();
}

Ответ 5

Здесь мои исследования в случае, если кто-то еще испытывает трудности с настройкой параметров миграции, которые были изменены/удалены. Основная проблема заключается в том, что GetPreviousVersion() не работает, если вы переименовали или удалили настройку в новой версии вашего приложения. Поэтому вам нужно сохранить параметр в своем классе Settings, но добавьте к нему несколько атрибутов/артефактов, чтобы вы случайно не использовали его в коде в другом месте, делая его устаревшим. Пример устаревшей настройки будет выглядеть так в VB.NET(можно легко перевести на С#):

<UserScopedSetting(),
DebuggerNonUserCode(),
DefaultSettingValue(""),
Obsolete("Do not use this property for any purpose. Use YOUR_NEW_SETTING_NAME instead."),
NoSettingsVersionUpgrade()>
Public Property OldSettingName() As String
  Get
    Throw New NotSupportedException("This property is obsolete")
  End Get
  Set
    Throw New NotSupportedException("This property is obsolete")
  End Set
End Property

Убедитесь, что вы добавили это свойство в одно и то же пространство имен/класс, в котором установлены ваши настройки приложения. В VB.NET этот класс называется MySettings и доступен в пространстве имен My. Вы можете использовать функции частичного класса, чтобы ваши устаревшие настройки не смешивались с вашими текущими настройками.

Полный кредит jsharrison за публикацию отличной статьи об этой проблеме. Вы можете прочитать более подробную информацию об этом там.