vb.net 定义应该保存 user.config 文件的自定义路径?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20120457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 15:54:57  来源:igfitidea点击:

Define a custom path where the user.config file should be saved?

.netvb.netapplication-settingsmy.settingsuser-config

提问by ElektroStudios

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

例如,如果我将编译的应用程序重命名为 from myapp.exeapp.exe那么当我运行重命名的可执行文件时,将在此路径中生成一个新的用户设置文件夹:

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 VBNETWinFormsmy own location to store the user.configfile, or any other solution using the applicationsettings infrastructure ? (not saving the settings on the registry or other things)

那么我如何解决这个问题,定义在VBNETWinForms我自己的位置来存储user.config文件,或者使用 applicationsettings 基础设施的任何其他解决方案?(不保存注册表或其他东西上的设置)

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?

PS:我读过这篇 SO 帖子,这是一个有点不同的问题,但无论如何我不明白所谓的解决方案Can I control the location of .NET user settings以避免丢失应用程序升级时的设置?

采纳答案by ??ssa P?ngj?rdenlarp

More info and a tidbit from the link which answers your question:

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

The "systemGUID or something" you reference is actually a hash of 2 things (Reference MSDN My.Settings):

您引用的“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.

Without a StrongName, your location is varying by path which is the problem you describe. Since BOTH eid and hash will use StrongName for the hash(es), the full path should remain the same even if they move it somewhere else or install a new version. When using a StrongName the credentials come from the app and the hashes don't change and the method of last resort (the exe path) is never used. Which answers your basic question: use a Strong Name and the path wont change.

如果没有 StrongName,您的位置因路径而异,这就是您描述的问题。由于 eid 和 hash 都将使用 StrongName 作为散列,因此即使将其移动到其他地方或安装新版本,完整路径也应保持不变。使用 StrongName 时,凭据来自应用程序,哈希值不会更改,并且永远不会使用最后的方法(exe 路径)。这回答了您的基本问题:使用强名称并且路径不会改变。

New releases/versions will create a sub folder tree under that folder for each version for Settings. The Upgrademethod for Settingsmentioned in the link (apparently) facilitates importing Settings from the/a previous version. A change in the EXE Name will cause the AppDomain.FriendlyName (3rd element) to change though.

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



Isolated Storage is another option, and it is not as hard as it first looks, but has similar behavior. With Iso, you dont specify a folder as it just creates one in an obscure location like Users\<User>\Isolated Storage\zhxytg\dhfyres\. The location CAN remain the same for all versions of the app, even if you rename it, if you use ClickOnce (so, this is another viable solution).

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

I think you have to use ClickOnce (StrongName as a replacement doesnt come up in MSDN) to get Application level evidence. As a side benefit, with ISO, even under the highest security a non admin user can read/write to shared files in ProgramData\AllUsers(as might be the case for a licence, or shared settings for an app suite) at least with W7. The app's hash permits it to write to that path, so it can do some things we normally can't do.

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

If you dont use ClickOnce, you can still get a stable folder per installand read/write to AllUsers. A new install (to a different folder) will result in a different hash and file location; same with changing the filename. Even if you managed to store the old location somewhere, a new install probably would not have rights to the old file (havent tried).

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

ISO removes varying by EXEName, but it does not use My.Settings. Instead you use IsolatedFileStreamscreated by IsolatedStorageFileobjects. And you'd have to take over organizing and managing the values and names of the various Settings. The type of Isolated Storage used (App / User) depends on the credentials available.

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

Isolated storage has its place, but seems to be overkill for Settings.

隔离存储有其一席之地,但似乎对设置来说有点过分。



You mentioned that you usually only use MySettings for trivial apps. As such, a StrongName simply to stabilize the path for Settings seems to be overkill. ISO is very interesting, but there is something much simpler. This third option falls into the or other thingsyou didn't want, but is veryflexible.

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

Build your own Settings Class around Serialization. For simple settings, these likely arent much more than a set of Name-Value Pairs {LastPath = "....."; FormLeft = x; FormTop = y ...}. Save these in a Dictionary(Of String, String)or Dictionary(Of enumSettings, String)and just serialize (save) the entire container:

围绕序列化构建您自己的设置类。对于简单的设置,这些可能不仅仅是一组名称-值对 {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

Getting the values back is just as simple. For more complex projects where there are many Types to save like Integer, Date, Array, ArrayList, List(of T) and so forth , create a UserOptions Class for them and serialize thatinstead.

取回值同样简单。对于有多种类型,以节省喜欢整数,日期,阵列,ArrayList中,列表(的T)等更复杂的项目,为他们和序列化创建一个USEROPTIONS类代替。

Note that you pass a filestream to the serializers, so you have full control over the name and location, such as C:\Users\<username>\AppData\Local\<Company>\<Product>\Settings.binThe location wont change by version, culture, assembly etc. It will stay where you put it.

请注意,您将文件流传递给序列化程序,因此您可以完全控制名称和位置,例如C:\Users\<username>\AppData\Local\<Company>\<Product>\Settings.bin位置不会因版本、文化、程序集等而改变。它将保留在您放置的位置。

This does run out of steam when you try to serilize Types like Point, Size and Font because Objects cannot be serialized directly. Especially, with ProtoBuff there are multiple options to convert these to something serializable on the fly or beforehand.

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

回答by Pantelis Natsiavas

I suppose you could also open your config file from specific location using ConfigurationManager.OpenExeConfigurationmethod.

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

Hope I helped!

希望我有所帮助!