Як ви зберігаєте налаштування user.config для різних версій збірки в .net?


146

В основному проблема полягає в тому, що щоразу, коли змінюється версія збірки (тобто користувач встановлює нову версію програми), всі їх налаштування скидаються за замовчуванням (або точніше, новий файл user.config створюється в папці з іншою версією номер як назва)

Як я можу зберегти ті самі налаштування під час оновлення версій, оскільки використання ini-файлів чи реєстру, здається, не рекомендується?

Коли ми використовували Clickonce, здавалося, що впораємося з цим, тому здається, що це треба зробити, але я не знаю як.



Ні, це посилається на замовчування, щоб не перевіряти файл у контролі версій (або я так зібрав). Це стосується специфічних для (Windows) налаштувань для кінцевого користувача
Davy8,

Просто питання, яке мені знадобилось, дякую :)
Бінарний Вор'єр

Я розмістив можливе рішення у наступній темі: stackoverflow.com/a/47921377/3223783 Сподіваюся, що це допоможе!
dontbyteme

Я розмістив можливе рішення в цій темі . Сподіваюся, що це допомагає!
dontbyteme

Відповіді:


236

ApplicationSettingsBase має метод під назвою Upgrade, який мігрує всі налаштування з попередньої версії.

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

Потім, при запуску програми ви перевіряєте, чи встановлений прапор, і якщо він є, викличте метод Оновлення , встановіть прапор неправдивим і збережіть конфігурацію.

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

Детальніше про метод оновлення читайте на MSDN . GetPreviousVersion також може бути варто подивитися , якщо вам потрібно зробити деякі призначені для користувача злиття.


2
Невелике запитання, що являє собою нову версію? Будь-яка частина номера 4 частини? Я використовую ClickOnce, так це інша тварина?
Заломлений Паладін

4
Який тип налаштувань повинен бути UpgradeRequired ? appSettings, userSettingsабо applicationSettings? Як налаштування користувача на Settings.Settings, коли перший раз він буде змінено на false, він більше ніколи не буде істинним. Нова версія не буде скидати , що UpgradeRequired назад до істинного.
dialex

4
@dialex Це має бути налаштування користувача. Параметри типу Додаток доступні лише для читання. Нові версії версій призводять до скидання налаштувань, оскільки налаштування зберігаються у певному варіанті.
Леонард Тіє

4
Я думаю, що я відповів на власне запитання. Якщо існує попередня версія файлу налаштувань, вона буде копіювати її значення в найновішу версію кожного разу при запуску програми, ймовірно, не те, що вам потрібно!
Х'ю Джеффнер

1
Я трохи здивований, що це не просто поведінка за замовчуванням; якщо налаштування програми нульові при запуску, і він знаходить попередню купу налаштувань, він завантажує їх.
SteveCinq

3

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


2

Ось моє дослідження на випадок, якщо комусь іншому важко перенести зміни, які були змінені / видалені. Основна проблема полягає в тому, що GetPreviousVersion()це не працює, якщо ви перейменували або видалили налаштування в новій версії програми. Тому вам потрібно зберегти налаштування у своєму Settingsкласі, але додати до нього кілька атрибутів / артефактів, щоб ви ненавмисно не використовували його в коді в іншому місці, роблячи його застарілим. Зразок застарілого налаштування виглядатиме так у VB.NET (його можна легко перекласти на C #):

<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 за публікацію чудової статті про цю проблему. Більш детальну інформацію про нього ви можете прочитати там.


1

Ось варіант щодо рішень, представлених тут, що інкапсулює логіку оновлення в абстрактний клас, з якого можуть виходити класи параметрів.

Деякі запропоновані рішення використовують атрибут DefaultSettingsValue, щоб вказати значення, яке вказує, коли попередні налаштування не завантажувались. Моя перевага - просто використовувати тип, значення якого за замовчуванням вказує на це. Як бонус, DateTime? є корисною інформацією про налагодження.

public abstract class UserSettingsBase : ApplicationSettingsBase
{
    public UserSettingsBase() : base()
    {
        // Accessing a property attempts to load the settings for this assembly version
        // If LastSaved has no value (default) an upgrade might be needed
        if (LastSaved == null)
        {
            Upgrade();
        }
    }

    [UserScopedSetting]
    public DateTime? LastSaved
    {
        get { return (DateTime?)this[nameof(LastSaved)]; }
        private set { this[nameof(LastSaved)] = value; }
    }

    public override void Save()
    {
        LastSaved = DateTime.Now;
        base.Save();
    }
}

Отримайте від UserSettingsBase:

public class MySettings : UserSettingsBase
{
    [UserScopedSetting]
    public string SomeSetting
    {
        get { return (string)this[nameof(SomeSetting)]; }
        set { this[nameof(SomeSetting)] = value; }
    }

    public MySettings() : base() { }
}

І використовуйте:

// Existing settings are loaded and upgraded if needed
MySettings settings = new MySettings();
...
settings.SomeSetting = "SomeValue";
...
settings.Save();

0

Якщо ваші зміни в налаштуваннях користувача виконуються програмно, як щодо збереження копії (просто) модифікацій в налаштуваннях користувача в окремому файлі, наприклад, user.customized.settings?

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

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


0

Ось як я впорався з цим:

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();
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.