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?

Community
  • 1
  • 1
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
  • 3
    Take note of Ian Boyd's comment in that link. Then note that very few serious apps (none on my system) make use of default/My.Settings. The default offers a lot of ease, but minimal flexibility and no protection. Using CompName\Product location for storage lets you do whatever you want (change the EXE name, import TrialVer settings, or encrypt settings if the contain something like an expiration date). A custom settings class can also use a binary serializer to save or load all the data without numerous assignments (`me.thisval = My.Settings.ThisVal`). – Ňɏssa Pøngjǣrdenlarp Nov 21 '13 at 15:40

2 Answers2

7

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

Hope I helped!

Pantelis Natsiavas
  • 5,293
  • 5
  • 21
  • 36
6

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):

<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.

New releases/versions will create a sub folder tree under that folder for each version for Settings. The Upgrade method for Settings mentioned 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.


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).

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.

If you dont use ClickOnce, you can still get a stable folder per install and 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).

ISO removes varying by EXEName, but it does not use My.Settings. Instead you use IsolatedFileStreams created by IsolatedStorageFile objects. 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.

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 things you didn't want, but is very flexible.

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:

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 that instead.

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.bin The location wont change by version, culture, assembly etc. It will stay where you put it.

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.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • first of all thankyou for the information. When I need to dev an app that has a lot of "critical" options then I always manage an INI file to Save/load all the settings, that's what I was reffering with this comment: `(not saving the settings on the registry *or other things*)`, Just I want to stop using INI file or registry or "other things" 'cause Microsoft give us a feature to manage settings easilly,the problem is that if the app has a lot of settings and you rename the app then all the settings is lost, – ElektroStudios Nov 28 '13 at 20:45
  • also I think that this way is not possibly yo make a portable install (with predefined settings I mean like you can do with an INI file in the app dir) ...at least until the settings file/dir location can't be defined by the developer. – ElektroStudios Nov 28 '13 at 20:45
  • I'm sorry but I only understanded around the 50% of the explanations that you've said, can you explain how to do this?: `if you go 'all in' on the Microsoft paradigm, you can stabilize the hash to a single, stable location.` with that you mean that exists a solution to my question using the microsoft .NET settings feature? the strong name has something to do with that quote? I'm a little bit lost, sorry!, and forgive my bad English. If you know how to resolve the question could you write in few lines an step by step guide for noobs if I'm not asking too much? – ElektroStudios Nov 28 '13 at 20:53
  • 1
    I agree that INI and registry are BAD and would not suggest that. A custom settings class to save itself though - even serialize itself - is pretty trivial and still falls into the *other things* category. I do not agree that the NET My.Settings is even close to ideal *unless* you want to do it their way from start to finish. #2: There ARE ways to save to a stable AppData or ProgramData locations, you just cant use My.Settings since MS/NET control the file location. #3 - I will edit – Ňɏssa Pøngjǣrdenlarp Nov 28 '13 at 20:58