10

If I rename my compiled application for example from myapp.exe to app.exe then when I run the renamed executable a new user settings folder is generated in this path:

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

So I loose all the saved settings.

Then how I could solve this problem defining in a VBNET WinForms my own location to store the user.config file, or any other solution using the applicationsettings infrastructure ? (not saving the settings on the registry or other things)

PS: I've read this SO post which is a little bit different question but anyways I didn't understood the supposed solution Can I control the location of .NET user settings to avoid losing settings on application upgrade?

4

2 回答 2

7

我想您也可以使用ConfigurationManager.OpenExeConfiguration方法从特定位置打开配置文件。

希望我有所帮助!

于 2013-11-25T06:42:36.350 回答
6

来自回答您问题的链接的更多信息和花絮:

您引用的“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 作为 hash(es),即使他们将其移动到其他地方或安装新版本,完整路径也应该保持不变。使用 StrongName 时,凭据来自应用程序,并且哈希值不会更改,并且永远不会使用最后的方法(exe 路径)。这回答了您的基本问题:使用强名称并且路径不会改变。

新版本/版本将为设置的每个版本在该文件夹下创建一个子文件夹树。链接中提到的Upgrade方法(显然)有助于从以前的版本导入设置。Settings但是,EXE 名称的更改将导致 AppDomain.FriendlyName(第三个元素)发生更改。


隔离存储是另一种选择,它不像最初看起来那么难,但具有类似的行为。使用 Iso,您无需指定文件夹,因为它只是在一个不起眼的位置(如Users\<User>\Isolated Storage\zhxytg\dhfyres\. 如果您使用 ClickOnce(因此,这是另一个可行的解决方案),该位置对于所有版本的应用程序都可以保持相同,即使您重命名它。

我认为您必须使用 ClickOnce (StrongName 作为 MSDN 中没有出现的替代品)来获得应用程序级别的证据。ProgramData\AllUsers作为附带的好处,使用 ISO,即使在最高安全性下,非管理员用户也可以至少使用 W7读取/写入共享文件(如许可证或应用程序套件的共享设置)。应用程序的哈希允许它写入该路径,因此它可以做一些我们通常不能做的事情。

如果您不使用 ClickOnce,您仍然可以在每次安装和读取/写入时获得一个稳定的文件夹AllUsers。新安装(到不同的文件夹)将导致不同的哈希和文件位置;与更改文件名相同。即使您设法将旧位置存储在某处,新安装也可能无权访问旧文件(未尝试过)。

ISO 删除了 EXEName 的变化,但它不使用 My.Settings。相反,您使用IsolatedFileStreamsIsolatedStorageFile对象创建。而且您必须接管组织和管理各种设置的值和名称。使用的隔离存储类型(应用程序/用户)取决于可用的凭据。

独立存储有它的位置,但对于设置来说似乎有点矫枉过正。


您提到您通常只将 MySettings 用于琐碎的应用程序。因此,一个 StrongName 只是为了稳定设置路径似乎是矫枉过正。ISO 非常有趣,但有一些更简单的东西。这第三个选项属于or other things您不想要的,但非常灵活。

围绕序列化构建您自己的设置类。对于简单的设置,这些可能不仅仅是一组名称-值对 {LastPath = "....."; FormLeft = x; FormTop = y ...}。将这些保存在Dictionary(Of String, String)or中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 位置不会因版本、文化、程序集等而改变。它将保留在您放置的位置。

当您尝试对 Point、Size 和 Font 等类型进行序列化时,这确实会失去动力,因为无法直接序列化对象。特别是,使用 ProtoBuff 有多个选项可以将这些转换为动态或预先可序列化的东西。

于 2013-11-28T19:27:09.213 回答