I want to get and set some application settings hidden for the user. In this case these are two tokens and two tokens that are being altered by the application. But still all four them are a secret to the application user.
I found two ways on MSDN and this forum.
Use a .config file. -> this sounds okay and I can change some values in it. But I see still a plain text file after publish.
Use the settings in the project properties. -> should it be? I read warnings about that this not so secure after all.
A lot of sites describe a web server solution while I just want to have a desktop solution.
Btw. It is not a commercial product, I am making a hobby project to learn more from C#.net.
If these files need to be altered by the application, you will need to persist these outside of the application so that the new settings will be loaded next time the app starts.
For this, you can always create a config (or settings) file and hide it in the System.IO.IsolatedStorage files for the assembly. This is still editable by the user, but its a bit of a pain to find - plus this will transfer over with roaming profiles so that the settings are used cross machine.
Something simple to help you start out:
IsolatedStorage.IsolatedStorageFile storage = IsolatedStorage.IsolatedStorageFile.GetUserStoreForAssembly();
string subdirectory = "SomeDirectory";
storage.CreateFile(System.IO.Path.Combine(subdirectory, "settings.config"));
Does the * existence* of the setting need to be kept secret, or just its value?
If the latter, I'd suggest encrypting the value you save to the .config file.
Related
In my applications there are some setting saved in the Properties.Settings.Default. These settings can be changed by the user(s) and needs to be saved locally on the computer. While I can save these setting, the problem is that it is only saved for the user currently logged in. Once an user changes a setting it has to be for all users of the computer. How can I accomplish this?
User scoped settings are just that, settings that an individual user can change and will only be saved for that user.
The application scoped settings will affect all users but they are not designed to be changed by a user.
You might want to consider a different approach to storing settings that you want users to be able to change but to affect all users of an application e.g. the Windows registry or an external xml file.
Another option is to use user scoped settings but to change the location to a centralised location so that all users use/save the same settings. See Store user settings into application folder for an option on how to do this.
When you open the Settings Designer window in Visual Studio, you have four values that you need to enter for each setting:
You need to set the Scope property to Application to have a setting that is the same for all users. For the full story, read the Using Application Settings and User Settings page on MSDN.
Application settings cannot be changed, only by hand before the application is run so I do not recommend that approach.
In my opinion, propagating the changes may be generally a bad approach. Since this config (user.config) is generally stored in the user's own folder (under Users), it should not be modified by another user (in fact, without administrator acces, another user cannot even access).
I might recommend using other places to store application specific settings: xml or config file near your application, or maybe the registry.
I would use an external Database for that Stuff...
But if you want it quick and simple just save it to a File on the Harddrive (for example C:\Program_Data\\settings.csv) i would use a csv file because it's not much work...
I am working on a software and want to create a configuration file for my application to store configurations that will be used at runtime. I have seen some software use a config.xml file to achieve this. The configuration file I want to use will have:
Cache folder location
Color scheme
Option to toggle caching
How to go about this? I am working with WPF.
In Visual Studio, add an "app.config" to your project. When you build your application, this will create an AppName.exe.config file, where AppName is the name of your executable. This is an XML config file that can contain your settings.
If theses options are user-specific, don't use app.config - that's for global application settings and you will clobber other users' settings. I'm bringing this point up because you mentioned caching options in your question, and in some applications, the choice to cache or not to cache is at the user level.
Instead, I would recommend that you create a domain object to store the configuration settings to, and serialize the object to a local folder in the current user's isolated storage folder.
When the application starts up, just look into the current user's isolated storage folder, confirm the serialized file exists, and deserialize back to the domain object.
as you are in WPF world, you also can use App.XAML for defining and using color schemes
Use standard .NET settings framework.
More details here: How is the logic behind storing program setting in text file like 'config.cfg'?
Also this will help http://msdn.microsoft.com/en-us/library/aa730869%28v=vs.80%29.aspx.
Although this article is a little old, not much changed since then in this realm.
I can't see anything on here but I do remember being told that If you want an application to update a config file then it needs to be under ...
**C:\Users\Ibrar Mumtaz\AppData**
Well somewhere there, the reason being is that the user should have permisions to update a config file here and not under the applications install folder. This is the impression that I am under and I'm fairly certain that this is definately the case. As I think I read that on here = p
My question is, is there anybody on here that can shine some light on this as this is the last feature I want to implement before I give my application out to test.
1) First thing is, an installer is needed to set up the folder and then drop my apps config file into it. I already am using the visial studio installer so I have my app packaged up but this point is throwing me off? How do I do this then? I just need someone to show how to do this and I should be O.K reconfiguring my app to look for the new home of the config file.
2) I should be able to work out how to find the folder and locate the config file found within it. As once I know the installer is chucking the config file out into the right folder where the user has permissions then it should be straight forward from there.
Thanks for reading.
UPDATE:
It was pretty straight foward, as the VS Installer has an option to add a special folder so all that was left was to access the folder programmatically and read and write to the config file. ONE PROBLEM? The ConfigurationManager class which I have used to create my config file for my application expects my config file to be local to the application and not miles away in a completey different part of the local FileSystem? Errr help here Plz?
Ibrar
If you are using the VS Settings file to create application setting keys, and have values that the user might want to change in runtime, and save his preferences, just set the scope of those settings to "User" instead of "Application".
That way you will have a setter method for them, and you can edit the Settings.Default instance, and when you are done call the Save() method to persist them to disk.
The file will be saved in the user's "AppData" folder, wherever it is, under some cryptic folder. But you needn't worry about it's location most of the time, since it will be read automatically on the next execute, and persisted to the same location on subsequent runs.
Afaik the installer can be extended with classes that do things.
On INSTALL-action to do could be to
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"My app name");
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
And vice-versa on uninstall.
App.config files are related to where the physical assembly is located I think.
Actually, if your app is running on the user's machine- it will have whatever permissions that user has. So most likely, you can expect to be able to write anywhere on the file system.
However it is possible the user would be running under a restricted acct, and thus not have the permissions. So you could just use the registry to store where your config file is (install folder), then when you try to update it, if it fails for permissions, ask the user to grant it.
Or you could use the Windows standard folders, as you were getting at, because doing so also separates out user data from application data.
Use the Environment.GetFolderPath () method to get the 'special folder' paths in your app.
http://www.programmersheaven.com/2/Les_CSharp_15_p2
http://msdn.microsoft.com/en-us/library/14tx8hby.aspx
If you are talking about application settings found on project Properties -> Settings tab, then there're two different types of settings: user-level and application-level.
If you need to change any settings in run-time, these would be user-level settings (http://msdn.microsoft.com/en-us/library/cftf714c.aspx) and all changes would be buried somewhere in the private folder in your user profile.
If you want to update application-level settings, your best shot would be to do that during software installation. In this case you don't need to look for the configuration file (YourApp.exe.config) anywhere but in the application folder. More likely you would need to create some sort of post-install event handler in your setup package and run some script or another application which would update data in YourApp.exe.config. Everything in the setup package will be executed with elevated priviledges and thus that configuration file would be writeable. BTW, this scenario applies to 2000 and XP, if the user is using limited user account type priviledges.
Because I did not technically find the answer I was looking for, after 6 months I have come back to my application and have managed to produce a solution that does not break my current architecture.
If you are implementing an application to make use of some of the features on offer by the ConfigurationManager then it offers a static method called:
ConfigurationManager.OpenMappedExeConfiguration(); // takes two arguements.
It can be used like this:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = returnUsersAppDataFolderPath();
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
e.g
fileMap.ExeConfigFileName = #"some file path external to your applications install folder."
remember to use '#' symbol in front to allow the compiler to literally treat the string on as is basis.
If the config file can be conveniently locally located then just use the:
ConfigurationManager.OpenExeConfiguration(string exePath)
Above is what you would typically use but for me i needed my config file to located under the users AppData folder so the first option is what I needed. And it does indeed work.
I hope this helps others as it does for me as I want to deploy my application to Win7 and vista environments therefore this question needed asking if I was to stick to using the ConfigurationManager it's a shame the method of choice in the end never really stood out in the first place = ).
If you want to read from your config file then leave a comment and I will show you how I managed to do that also.
I've been trying to modify my application to deploy and update using ClickOnce. I've managed to get the program working but I'm having trouble with the program configuration. My program uses a custom XML configuration file located in the application directory. This raises 2 major problems.
1.) The configuration file is very hard to get to. Without knowledge of how ClickOnce works the user will not be able to locate it.
2.) Currently if I change the configuration file ClickOnce automatically "updates" the configuration file to the original version, destroying my configuration.
Ideally I would like it to move the configuration file to another location and create a start menu shortcut to it next to my application. But if I change the program to do this can I still deploy the application using ClickOnce?
Thanks in advance,
Fr33dan
Why don't you put a copy of the configuration in the users app data folder (this can be done on first run) - then have a button in your application which opens it (either externally or in your application)?
You can always store your configuration data in the Application Settings. This won't get overwritten on every ClickOnce change or update (unless you change the Type of the setting). You can then create a simple form to update it. That's the technique many .NET developers use for screensavers.
There are a number of things you can do here to mitigate this as a problem.
Firstly, using what's already there - the configuration data has two parts (excuse me as I'm working from memory) app config and user config. The app config is basically defined when the app is pulled down however the user config is just that - you set up the defaults and then, once set by the application on behalf of the user, it won't be overwritten when the app is updated.
It should be straightforward enough to provide a configuration editor - something as simple as a two column grid would be sufficient with a read only label column and an editable value column (although you're going to be somewhat challenged on validation).
Alternatively, if you're happier with a more traditional configuration, then you need precisely 1 user value and that would be the location for the config file... if you don't know if (or can't find the file) prompt to create, dump your default config to the specified location from a resource within you app and then you've got your config file and away you go.
One project I worked on, we made the app download a configuration file from the server it was deployed from (this was done on each startup to cope with if app was added to the Start Menu and cached). The ClickOnce API gives you the server address.
On another project we just pass a few config values as query strings to the ClickOnce app, these were generated by the Asp.net page that had the link to the app.
This allowed customers to change the config for their site without having to resign etc.
(This does not help with per-user config)
What is the recommended location to save user preference files? Is there a recommended method for dealing with user preferences?
Currently I use the path returned from typeof(MyLibrary).Assembly.Location as a default location to store files generated or required by the application.
EDIT:
I found two related/interesting questions:
Best place to save user information for Windows XP and Vista applications
What's the way to implement Save / Load functionality?
EDIT #2:
This is just a note for people like me who had never used settings before.
Settings are pretty useful, but I had to do a whole bunch of digging to figure out what was going on (coming from the Python world, not something I am used too). Things got complicated as I wanted to save dictionaries and apparently they can't be serialized. Settings also seem to get stored in 3 different files depending on what you do. There is an app.config, user.config and a settings.setting file. So here are two more links that I found useful:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/ddeaca86-a093-4997-82c9-01bc0c630138
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/efe370dc-f933-4e55-adf7-3cd8063949b0/
You can use the Application Settings easily enough.
If you haven't done so before just right click on the project and choose Properties. Select the Settings tab. Make sure you chose "User" for the scope (otherwise the setting is read-only).
The code to access this is simple:
forms.Width = Application1.Properties.Settings.Default.Width;
If you need to save it:
Application1.Properties.Settings.Default.Width = forms.Width;
Application1.Properties.Settings.Default.Save();
In the sample above, Width is the custom setting name you define in the Settings tab and Application1 is the Namespace of your application.
Edit: Responding to further questions
You mentioned you wanted to store Dictionary objects in the Settings. As you discovered, you can't do this directly because Dictionary objects are not serializable. However, you can create your own serializable dictionary pretty easily. Paul Welzer had an excellent example on his blog.
You have a couple of links which sort of muddy the situation a little. Your original question is where to save "User Preference Files". I'm pretty certain Microsoft's intention with the Settings functionality is exactly that... storing user skin preferences, layout choices, etc. It not meant as a generic repository for an application's data although it could be easily abused that way.
The data is stored in separate places for a good reason. Some of the settings are Application settings and are read-only. These are settings which the app needs to function but is not specific to a user (for example, URIs to app resources or maybe a tax rate). These are stored in the app.config.
User settings are stored in an obfuscated directory deep within the User Document/Settings folder. The defaults are stored in app.config (I think, can't recall for certain off the top of my head) but any user changes are stored in their personal folder. This is meant for data that changes from user to user. (By "user" I mean Windows user, not your app's user.)
Hope this clarified this somewhat for you. The system is actually pretty simple. It might seem a little foreign at first but after a few days of using it you'll never have to think of it again... it just works.
When running as non-admin or on Vista you can't write to the "Program files" folder (or any sub folder of it).
The correct location to store user preference is (replace MyCompanyName and MyApplicationName with the correct names, obviously)
On disk:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\MyCompanyName\\MyApplicationName"
Or in the registry under the key:
HKEY_CURRENT_USER\Software\MyCompanyName\MyApplicationName
Those location are per-user and they work with non-admin user, several users using the same computer, fast user switching, terminal services and all the other ways people can interact with your software.
If you need a common location for all users then:
It will only work when the user run as an administrator
It will not work reliably on Vista
You have to take care of everything yourself (like two users running the application on the same computer at the same time via fast user switching).
and the locations are:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationCommonData) + "\\MyCompanyName\\MyApplicationName"
Or in the registry under the key:
HKEY_LOCAL_MACHINE\Software\MyCompanyName\MyApplicationName
You can use isolated storage. You can isolate by user, assembly and/or domain.
Introduction to Isolated Storage
http://msdn.microsoft.com/en-us/library/3ak841sy(VS.80).aspx
Types of Isolation
http://msdn.microsoft.com/en-us/library/eh5d60e1(VS.80).aspx
the following seems to be the best option:
Application.UserAppDataPath