定义应保存user.config文件的自定义路径



如果我将已编译的应用程序从myapp.exe重命名为app.exe,则当我运行重命名的可执行文件时,会在以下路径中生成一个新的用户设置文件夹:

C:Users{User}AppDataLocal{CompanyName}{ExecutableName}_Url_{SystemGUID or something strange}

所以我丢失了所有保存的设置。

那么,如何解决在VBNET WinForms中定义自己的位置以存储user.config文件的问题,或者使用应用程序设置基础结构的任何其他解决方案?(不保存注册表上的设置或其他内容)

附言:我读过这篇SO文章,这是一个有点不同的问题,但无论如何,我不理解所谓的解决方案。我可以控制.NET用户设置的位置,以避免在应用程序升级时丢失设置吗?

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

希望我能帮上忙!

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

您引用的"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,因此即使他们将其移动到其他地方或安装新版本,完整路径也应保持不变。当使用StrongName时,凭据来自应用程序,哈希不会更改,也不会使用最后的方法(exe路径)。这回答了你的基本问题:使用一个强名称,路径不会改变。

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


隔离存储是另一种选择,它不像最初看起来那么难,但有类似的行为。使用Iso,您不需要指定文件夹,因为它只是在Users<User>Isolated Storagezhxytgdhfyres之类的模糊位置创建一个文件夹。对于所有版本的应用程序,即使您重命名它,如果您使用ClickOnce,位置也可以保持不变(因此,这是另一个可行的解决方案)。

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

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

ISO删除了EXEName的变化,但它不使用MySettings。而是使用由IsolatedStorageFile对象创建的IsolatedFileStreams。你必须接管组织和管理各种设置的值和名称。使用的独立存储的类型(应用程序/用户)取决于可用的凭据。

独立存储有其用武之地,但对"设置"来说似乎有些过头了。


你提到你通常只对琐碎的应用程序使用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>AppDataLocal<Company><Product>Settings.bin。位置不会因版本、区域性、程序集等而更改。它将保留在您放置的位置。

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

相关内容

  • 没有找到相关文章

最新更新