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

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

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

Итак, я потерял все сохраненные настройки.

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

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

Ответ 1

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

"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 ваше местоположение изменяется по пути, который является проблемой, которую вы описываете. Поскольку BOTH eid и hash будут использовать StrongName для хэшей (ов), полный путь должен оставаться тем же, даже если они перемещают его где-то еще или устанавливают новую версию. При использовании StrongName учетные данные поступают из приложения, а хеши не изменяются, и метод последнего действия (путь EXE) никогда не используется. Что отвечает на ваш основной вопрос: используйте сильное имя и путь не изменится.

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


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

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

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

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

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


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

Создайте свой собственный класс настроек вокруг сериализации. Для простых настроек эти, вероятно, arent гораздо больше, чем набор пар Name-Value Pairs {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 существует несколько вариантов их преобразования в нечто сериализуемое "на лету" или заранее.

Ответ 2

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

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