Определить пользовательский путь, где файл user.config должен быть сохранен?

Если я переименую мое скомпилированное приложение, например, из myapp.exe в app.exe затем, когда я запускаю переименованный исполняемый файл, по этому пути создается новая папка пользовательских настроек:

C:\Users\{User}\AppData\Local\{CompanyName}\{ExecutableName}_Url_{SystemGUID or something strange}

Поэтому я теряю все сохраненные настройки.

Тогда как я мог решить эту проблему, определив в VBNETWinForms мое собственное место для хранения user.config файл или любое другое решение, использующее инфраструктуру настройки приложений? (без сохранения настроек в реестре или других вещей)

PS: я прочитал этот пост, который представляет собой немного другой вопрос, но в любом случае я не понял предполагаемого решения. Могу ли я контролировать расположение пользовательских настроек.NET, чтобы избежать потери настроек при обновлении приложения?

2 ответа

Решение

Больше информации и лакомый кусочек по ссылке, которая отвечает на ваш вопрос:

"SystemGUID или что-то", на которое вы ссылаетесь, на самом деле представляет собой хэш из двух вещей (см. MSDN My.Settings):

<eid> is the URL, StrongName, or Path, based on the evidence available to hash.  
<hash> is a SHA1 hash of evidence gathered from the CurrentDomain, 
    in the following order of preference: 
    - StrongName 
    - URL If neither of these is available, use the .exe path.

Без StrongName ваше местоположение меняется в зависимости от пути, что и является проблемой, которую вы описываете. Поскольку оба eid и hash будут использовать StrongName для хэшей, полный путь должен оставаться прежним, даже если они переместят его куда-нибудь еще или установят новую версию. При использовании StrongName учетные данные поступают из приложения, и хэши не меняются, а метод последней инстанции (путь exe) никогда не используется. Что отвечает на ваш основной вопрос: используйте строгое имя и путь не изменится.

Новые выпуски / версии будут создавать дерево подпапок в этой папке для каждой версии настроек. Upgrade метод для Settings Упомянутая в ссылке (видимо) облегчает импорт настроек из / предыдущей версии. Изменение имени EXE приведет к изменению AppDomain.FriendlyName (3-й элемент).


Изолированное хранилище - это еще один вариант, и он не так сложен, как кажется на первый взгляд, но имеет аналогичное поведение. С помощью Iso вы не указываете папку, так как она просто создает папку в неясном месте, например Users\<User>\Isolated Storage\zhxytg\dhfyres\, Расположение может оставаться одинаковым для всех версий приложения, даже если вы переименуете его, если вы используете ClickOnce (так что это еще одно жизнеспособное решение).

Я думаю, что вы должны использовать ClickOnce (StrongName в качестве замены не подходит в MSDN), чтобы получить доказательства уровня приложения. Дополнительным преимуществом является то, что с ISO даже при самом высоком уровне безопасности пользователь без прав администратора может читать / записывать в общие файлы в ProgramData\AllUsers (как в случае с лицензией или общими настройками для набора приложений), по крайней мере, с W7. Хеш приложения позволяет ему писать по этому пути, поэтому он может делать некоторые вещи, которые мы обычно не можем делать.

Если вы не используете ClickOnce, вы можете получить стабильную папку для каждой установки и читать / писать в AllUsers, Новая установка (в другую папку) приведет к другому хешу и расположению файла; То же самое с изменением имени файла. Даже если вам удалось где-то сохранить старое местоположение, новая установка, вероятно, не будет иметь прав на старый файл (не пробовал).

ISO удаляет изменения по EXEName, но не использует My.Settings. Вместо этого вы используете IsolatedFileStreams создано IsolatedStorageFile объекты. И вам придется взять на себя организацию и управление значениями и именами различных настроек. Тип используемого изолированного хранилища (приложение / пользователь) зависит от доступных учетных данных.

Изолированное хранилище имеет свое место, но, похоже, излишне для настроек.


Вы упомянули, что вы обычно используете MySettings только для тривиальных приложений. Таким образом, StrongName просто для стабилизации пути к настройкам кажется излишним. ISO очень интересна, но есть кое-что намного проще. Этот третий вариант попадает в or other things ты не хотел, но очень гибкий.

Создайте свой собственный класс настроек вокруг сериализации. Для простых настроек они, вероятно, не намного больше, чем набор пар имя-значение {LastPath = "....."; FormLeft = x; FormTop = y ...}. Сохраните их в Dictionary(Of String, String) или же Dictionary(Of enumSettings, String) и просто сериализовать (сохранить) весь контейнер:

Dim bf As New BinaryFormatter
Using fs As New FileStream(myFile, FileMode.OpenOrCreate)
    bf.Serialize(fs, _UserOpts)   
End Using

Вернуть значения так же просто. Для более сложных проектов, в которых нужно сохранить много типов, например Integer, Date, Array, ArrayList, List(of T) и т. Д., Создайте для них класс UserOptions и сериализуйте его.

Обратите внимание, что вы передаете файловый поток сериализаторам, чтобы иметь полный контроль над именем и местоположением, например C:\Users\<username>\AppData\Local\<Company>\<Product>\Settings.bin Местоположение не будет меняться в зависимости от версии, культуры, сборки и т. Д. Оно останется там, где вы его положили.

Это не работает, когда вы пытаетесь сериализовать типы, такие как точка, размер и шрифт, потому что объекты не могут быть сериализованы напрямую. В частности, в ProtoBuff есть несколько опций для преобразования этих файлов в сериализуемые на лету или заранее.

Я полагаю, вы также можете открыть свой файл конфигурации из определенного места, используя метод ConfigurationManager.OpenExeConfiguration.

Надеюсь, я помог!

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