Чи можу я контролювати розташування користувальницьких налаштувань .NET, щоб уникнути втрати налаштувань під час оновлення програми?


104

Я намагаюся налаштувати розташування user.configфайлу. Наразі він зберігається з номером хешу та версії

%AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\

Я хочу, щоб це було агностично відносно версії програми

%AppData%\[CompanyName]\[ProductName]\

Чи можна це зробити і як? Які наслідки? Чи втратить користувач свої налаштування від попередньої версії після оновлення?


Хоча відповідь узбонеса є інформативною щодо розташування файлів, я вважаю, що Ian правильніше щодо оновлення.
Ентоні Мастрен

4
@AnthonyMastrean Я особисто вважаю, що будь-які важливі параметри не повинні покладатися на інфраструктуру ApplicationSettings, надану моїм Microsoft. Мукса повинна просто зберігати налаштування %AppData%\[CompanyName]/[ProductName]там, де ми можемо вірити, що вони залишаться.
Ян Бойд

2
Без сумніву, мій постійний досвід роботи із вбудованими програмами та налаштуваннями користувачів був жахливим. Я рекомендую файли json у додатках чи програмах.
Ентоні Мастрен

Ви також можете зберігати свої налаштування в реєстрі. Дивіться stackoverflow.com/a/12127888/1273550 для альтернативної реалізації параметрів параметрів.
Раві Патель

Відповіді:


39

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

Щодо другого питання, це залежить від того, як ви розгортаєте додаток. Якщо ви розгортаєтесь через .msi, то у властивостях програми налаштування (з якого створено msi) є два хеші, «код оновлення» та «код продукту». Вони визначають, як можна встановити msi та оновити його, перезаписати чи встановити поруч із будь-якою іншою версією цього самого додатка.

Наприклад, якщо у вас є дві версії програмного забезпечення і вони мають різні "оновлення" коди, то до Windows вони є абсолютно різними частинами програмного забезпечення незалежно від того, що називається. Однак якщо код «оновлення» той самий, але код «продукт» відрізняється, тоді, коли ви намагатиметесь встановити 2-й msi, він запитає, чи хочете ви оновити, і в цей час передбачається скопіювати значення з стара конфігурація до нової конфігурації. Якщо обидва значення однакові, а номер версії не змінився, то новий конфігурація буде знаходитись у тому самому місці, що і старий конфігурація, і йому нічого не доведеться робити. Документація MSDN

ClickOnce дещо інший, тому що його базується більше на версії № ClickOnce та URL-адресі, проте я виявив, що доки ви продовжуватимете "Опублікувати" до того самого місця, нова версія програми продовжуватиме використовувати існуючий конфіг. ( посилання на те, як ClickOnce обробляє оновлення )

Я також знаю , що є спосіб вручну об'єднати конфіги під час установки з MSI , використовуючи призначені для користувача сценарії установки, але я не пам'ятаю точні кроки , щоб зробити це ... (див цю посилання , як зробити це за допомогою Інтернету. конфігурація)


Чи не код оновлення є тим, який повинен залишатися постійним, а код продукту тим, який повинен змінюватися між випусками? blogs.msdn.com/b/pusu/archive/2009/06/10/understanding-msi.aspx
estanford

До! Ви маєте рацію, не можу повірити, що я зрозумів це назад (і на це пішло два роки). Це було схоже на робочий підпис на деякий час в моєму минулому :(
uzbones

Чи означає це, що лише користувач, що встановлює, оновлює її налаштування?
Micha Wiedenmann

79

Я хотів додати цей цитований текст як посилання на те, коли у мене буде ця проблема в майбутньому. Нібито ви можете доручити інфраструктурі ApplicationSettings скопіювати налаштування з попередньої версії, зателефонувавши Оновити :

Properties.Settings.Value.Upgrade();

Від клієнта Налаштування Довідка в блозі: ( архів )

Питання: Чому на шляху user.config є номер версії? Якщо я розгорніть нову версію свого додатка, чи не втратить користувач усі налаштування, збережені попередньою версією?

Відповідь: Є кілька причин, чому шлях user.config є чутливим до версії.

(1) Для підтримки одночасного розгортання різних версій програми (це можна зробити, наприклад, Clickonce). Можливо, для різних версій програми збережені різні налаштування.

(2) Під час оновлення програми клас налаштувань може бути змінений і може бути не сумісний із збереженим, що може призвести до проблем.

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

Питання: Гаразд, але як я можу знати, коли зателефонувати до оновлення?

Відповідь: Добре запитання. У Clickonce, коли ви встановлюєте нову версію свого додатка, ApplicationSettingsBase виявить його та автоматично оновить налаштування для вас у точковому завантаженні. У випадках, що не стосуються Clickonce, автоматичного оновлення немає - вам потрібно зателефонувати Оновити самостійно. Ось одна ідея для визначення, коли зателефонувати до оновлення:

Майте булеву настройку під назвою CallUpgrade і надайте їй значення за замовчуванням true. Коли ваш додаток запускається, ви можете зробити щось на кшталт:

if (Properties.Settings.Value.CallUpgrade)
{
   Properties.Settings.Value.Upgrade();
   Properties.Settings.Value.CallUpgrade = false;    
}

Це забезпечить виклик Upgrade () тільки в перший раз, коли програма запускається після розгортання нової версії.

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


3
ЦЕ ВСЕ РОБОТАЄ! Я використовував просто просте if(CallUpgrade) { Upgrade(); }твердження.
Ентоні Мастрен

@Ian Boyd: Мені подобається ця ідея, і я абсолютно не вражений можливим рішенням, проте мене збентежило одне. У мене немає участі у Properties.Settings.Value мене, Properties.Settingsале я щось пропускаю або це для вас конкретно?
Переломлений Паладін

8
Це добре працює, але я нагадую читачам, що шлях конфігурації до, але виключаючи номер версії, повинен бути однаковим. тобто див. відповідь @ Amr. Наприклад, якщо нова версія програми запущена з іншого файлового шляху, ніж попередня версія, Upgradeвона не працює.
Стівен Швенсен

1
@RefractedPaladin цеProperties.Settings.Default.Upgrade()
Стівен Швенсен

5
Не забудьте додати, Properties.Settings.Default.Save();змінивши його на false :-)
Джефф

32

Файл user.config зберігається в

c:\Documents and Settings>\<username>\[Local Settings\]Application Data\<companyname>\<appdomainname>_<eid>_<hash>\<verison>

<c:\Documents and Settings>- це каталог даних користувачів, який не є роумінгом (Місцеві налаштування вище) або роумінгом.
<username>- це ім'я користувача.
<companyname>- це значення CompanyNameAttribute, якщо воно є. В іншому випадку ігноруйте цей елемент.
<appdomainname>є AppDomain.CurrentDomain.FriendlyName. Зазвичай це за замовчуванням ім'я .exe.
<eid>- це URL-адреса, StrongName або Шлях на основі доказів, доступних для хешу.
<hash>- це хеш-доказ SHA1, зібраний з CurrentDomain, у такому порядку уподобань:
1. StrongName
2. URL:
Якщо жодне з них не доступне, використовуйте шлях .exe.
<version>- це налаштування AssemblyIners'sVersionAttribute.

Повний опис тут http://msdn.microsoft.com/en-us/library/ms379611.aspx


4

(Я додав би це як коментар до відповіді @ Amr, але у мене ще недостатньо представників, щоб це зробити.)

Інформація в статті MSDN дуже ясно , і , здається, до цих пір застосовуються. Однак не зазначається, що хеш SHA1 записується в кодовану базу 32, а не на більш типову основу 16.

Я вважаю, що алгоритм, який використовується, реалізований в ToBase32StringSuitableForDirName, який можна знайти тут, у довідковому джерелі Microsoft .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.