Могу ли я контролировать расположение пользовательских настроек.NET, чтобы избежать потери настроек при обновлении приложения?
Я пытаюсь настроить местоположение user.config
файл. В настоящее время он хранится с хешем и номером версии
%AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\
Я хочу, чтобы он был независим от версии приложения
%AppData%\[CompanyName]\[ProductName]\
Можно ли это сделать и как? Каковы последствия? Пользователь потеряет свои настройки из предыдущей версии после обновления?
4 ответа
Чтобы ответить на первый вопрос, технически вы можете поместить файл туда, куда хотите, однако вам придется кодировать его самостоятельно, так как место по умолчанию для файла - это первый из ваших двух примеров. ( ссылка на то, как это сделать самостоятельно)
Что касается второго вопроса, это зависит от того, как вы развертываете приложение. Если вы развертываете через MSI-файл, то в свойствах проекта установки (из которых построен MSI-файл) есть два хэша: "код обновления" и "код продукта". Они определяют, как можно установить msi, а также обновлять, перезаписывать или устанавливать помимо любой другой версии того же приложения.
Например, если у вас есть две версии вашего программного обеспечения, и у них разные коды "обновления", то для окон они представляют собой совершенно разные части программного обеспечения независимо от того, как называется. Однако, если код "обновления" такой же, но код "продукта" отличается, тогда, когда вы попытаетесь установить 2-ю версию MSI, он спросит вас, хотите ли вы обновить, и в это время предполагается скопировать значения из старый конфиг в новый конфиг. Если оба значения одинаковы, а номер версии не изменился, то новый конфиг будет в том же месте, что и старый конфиг, и ему ничего не нужно будет делать. Документация MSDN
ClickOnce немного отличается, потому что он основан больше на версии # и пути URL ClickOnce, однако я обнаружил, что, пока вы продолжаете "Публиковать" в том же месте, новая версия приложения будет продолжать использовать существующий конфиг. ( ссылка на то, как ClickOnce обрабатывает обновления)
Я также знаю, что есть способ объединить конфиги вручную во время установки MSI, используя пользовательские сценарии установки, но я не помню точных шагов, чтобы сделать это... (см. Эту ссылку, чтобы узнать, как это сделать с помощью Интернета. конфигурации)
Я хотел добавить этот цитируемый текст в качестве справки, когда у меня возникнет эта проблема в будущем. Предположительно, вы можете указать инфраструктуре ApplicationSettings скопировать настройки из предыдущей версии, вызвав команду Upgrade:
Properties.Settings.Value.Upgrade();
Из настроек клиента FAQ в блоге: ( архив)
Q: Почему в пути user.config указан номер версии? Если я разверну новую версию своего приложения, не потеряет ли пользователь все настройки, сохраненные в предыдущей версии?
A: Есть несколько причин, по которым путь user.config чувствителен к версии.
(1) Для поддержки параллельного развертывания различных версий приложения (вы можете сделать это, например, с помощью Clickonce). Для разных версий приложения могут быть сохранены различные настройки.
(2) При обновлении приложения класс настроек может быть изменен и может быть несовместим с сохраненными данными, что может привести к проблемам.
Однако мы упростили обновление настроек с предыдущей версии приложения до последней. Просто вызовите ApplicationSettingsBase.Upgrade(), и он извлечет настройки из предыдущей версии, которые соответствуют текущей версии класса, и сохранит их в файле user.config текущей версии. У вас также есть возможность переопределить это поведение в классе настроек или в реализации вашего провайдера.
Q: Хорошо, но как мне узнать, когда позвонить в Upgrade?
A: Хороший вопрос. В Clickonce, когда вы устанавливаете новую версию вашего приложения, ApplicationSettingsBase обнаружит его и автоматически обновит настройки для вас в момент загрузки настроек. В случаях, не связанных с Clickonce, автоматическое обновление не производится - вам нужно позвонить в Upgrade самостоятельно. Вот одна идея для определения, когда вызывать Upgrade:
Имейте логическую настройку CallUpgrade и присвойте ей значение по умолчанию true. Когда ваше приложение запускается, вы можете сделать что-то вроде:
if (Properties.Settings.Value.CallUpgrade)
{
Properties.Settings.Value.Upgrade();
Properties.Settings.Value.CallUpgrade = false;
}
Это обеспечит вызов Upgrade () только при первом запуске приложения после развертывания новой версии.
Я ни на секунду не верю, что это могло бы действительно сработать - Microsoft никак не могла бы предоставить такую возможность, но метод все тот же.
Файл 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 или Path, основанные на доказательствах, доступных для хэширования.<hash>
является хешем доказательств SHA1, собранным из CurrentDomain, в следующем порядке предпочтения:
1. StrongName
2. URL:
Если ни один из них не доступен, используйте путь.exe.<version>
является значением AssemblyVersionAttribute для AssemblyInfo.
Полное описание здесь http://msdn.microsoft.com/en-us/library/ms379611.aspx
(Я бы добавил это в качестве комментария к ответу @Amr, но мне пока не хватает представителя.)
Информация в статье MSDN очень ясна и, кажется, все еще применима. Однако не следует упоминать, что хэш SHA1 записан в кодированной базе 32, а не в более типичной базе 16.
Я считаю, что используемый алгоритм реализован в ToBase32StringSuitableForDirName
, который можно найти здесь в справочном источнике Microsoft.