C# -> Updating an AppSettings.config file on Win7/Vista - c#

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.

Related

How to create Application.exe.config in application directory

So I recently updated my application to support a new feature. In the past if the configuration file was deleted by the user it wasn't a big deal. This new feature requires it to exist, and one of the requirements is that, the file exists in the application's installation directory.
I have notice when the file is deleted ( depending on variables I have not figured out ) I get a .NET notification that the configuration file is missing or corrupt. Currently my program then crashes ( I still have to figure out how to duplicate this behavior ) which is the reason for this question.
I am familar with ConfigurationManager. I am having trouble writting the file once the default values are loaded. Forcing a Save for some reason does not seem to recreate the file, at least not in the installation directory, which is a requirement.
I am looking for guidence on how to handle this corner case in an elegant manner. I would post code, honestly its just all failed attempts, which while my attempts do generate a file the contents are not the settings I am looking for.
I am willing to post anything that might be able to help.
Stop using the built-in config support and just use write/read to a file called something.exe.config using the standard XML classes and if that gets deleted, just re-create it from values hard-coded in the executable.
The config file support is supposed to make things easier, if you need to do stuff where it makes things difficult, don't use it.
Something like
var wcfm = new WebConfigurationFileMap();
Configuration newConfig = WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
newConfig.Save();
doesn't work?
You dont. Under normal conditions the program can not write into it's install directory - this is a standard windows security issue and the reason why app application data should reside ni external (from the exe's point) driectories.
If an admin deletes the config file, crash, ask for reinstall. There is nothing you can RELIABLY do, as you can not assume you can write into the folder at runtime. A message followed by an event log entry is the best approach here. Users are not supposed to delete parts of the application.

WPF app.config writing

I've seen this solution proposed, but doesn't seem to work for me:
Configuration oConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
oConfig.AppSettings.Settings["PreferenceToRemember"].Value = “NewValue”;
oConfig.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
It successfully changes the value in memory, but does not save it back to the config file.
I'm trying to do this in a Wpf app, if that makes any difference.
Or is there a preferred way to save user settings to a file?
If your app is installed in \Program Files\ then it may not have permissions to write to the file. Generally, app.config files are modified by hand (in my experience, at least). If you want to persist user preferences, you should look into a .settings file as these are created in the %appdata% (or %localappdata%) directory, which is under the user's directory.
My guess is that using OpenExeConfiguration does not actually open the associated file. For example, you could be running from a XAP, where there would still be a .exe.config inside the .xap, but it doesn't map to an actual file on the filesystem.
You could probably check this by seeing if oConfig.HasFile is true or not.
If my guess is correct, then you'll need to use the OpenExeConfiguration(string) overload; the sample on the MSDN page has a reasonable way to get the right filename, although my first instinct was instead to try System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase.

Why can't my C# app create files in Windows 7?

I have a C# app that creates a settings file for itself to store the current state of certain visual elements. This app works just fine on any machine that isn't running Windows 7, but on those machines we get an error that the settings file can't be created because the user doesn't have permission. Now, I could fix this issue by going to each computer, logging in as the administrator and giving the user read and write access on the program folder for the application that we've installed, but there has to be a better way.
It seems like in XP, you got write access on the folders you created by default, but that isn't the case anymore. Is there a setting I need in the setup package to make this work?
The point is that you shouldn't be storing settings files in the program folder. Microsoft have advised against this for a long time, but started making things stricter with Vista IIRC.
Use Environment.SpecialFolders.ApplicationData (etc) to find the most appropriate place to put settings. Or use the .NET settings infrastructure which does this automatically for you.
are you trying to create files in the installation folder? you should be using the user data folder for data and not the installation folders. Use the Environment.SpecialFolders.ApplicationData folder to get a folder you can write to.
You're probably running as an administrator on your non-Windows 7 machine which an write anywhere. Be sure to save any per user instance data in their AppData folder (roaming if it should follow them from computer to computer, or local if its a cache or local to taht machine only). If you need to share settings between users, use the C:\ProgramData folder with the appropriate permissions.
A program shouldn't try to store settings in its installation directory.
Be sure to use the SpecialFolders along with Environment.GetFolderPath to get the right locations needed. You should never hard code paths because they can be different between versions AND languages. (I know in the German version of XP it wasn't Program Files but Programme!)
this app works just fine on any machine that isn't running Windows 7
Wrong! It only works on those machines if you run as administrator. I think you'll find your program is broken on Windows XP as well if you try to run it on just about any business computer rather than a home computer.
Instead, this kind of information needs to go in one of the special Application Data folders.
This is a security flaw in your program because your program is writing information to the program directory (which is, and should be, protected.) If it's a situation of correcting the root cause, consider using the SpecialFolder enumeration or the static members on Application like like CommonAppDataPath to write your information to a more appropriate location.
Assuming the typical approach to writing a file via a path, this is a trivial fix and there's no good "expediency" reason to not correct the root cause. If you're not sure about how to manipulate the path, consider using Path.Combine(). It does it for you.
In general, you shouldn't be writing program data to any folder underneath Program Files (even if you created the folder). You should use the Environment.GetFolderPath(...) to figure out where to put your application specific data. You can pass in one of many enums defined here -- you probably want Environtment.SpecialFolder.CommonApplicationData
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
I do not see how any of this is an actaul answer. I need to be able to write a report and have it saved the users documents folder the same folder I used to read the xml files I am writing the report from.

Configuration file with ClickOnce deployment

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)

Writing drive C: in Windows 7/Vista

I am developing an application that saves its settings in the install folder. If I install the app in the Program Files on drive C: and attempt to write the settings file I get an exception and that's it.
I know that the User Account Control (UAC) migth be the one that is not letting my app modify the content of the file.
I need help with the following issues:
Do the file editing in such a way that at least an UAC warning should be shown and if I answer yes the file becomes writable
If there is no way to edit the file on drive C: I need a method to store data somewhe
A more generic question would be:
How to create a C# program that after installing it to C:\Program Files\MyProgram under Windows Vista can manipulate (create/edit/delete) an .ini file in the installation directory? This file should be the same for all users.
Why don't you store the settings in a user-specific location like C:\Users\Username\AppData?
That way different users can have different settings on the same machine. Also, this is the recommended location for settings and the like.
Building on the answer from Ben S, check out the Environment.GetFolderPath method.
This method allows you to abstract away the specific location and just use a known SpecialFolder path instead (ie SpecialFolder.ApplicationData).
The fact that you are getting an exception means that your program is Vista/7 aware somehow. I am not totally sure what setting (in a C# project) triggers that. But if you can make your app 'pretend' it is an XP application, Vista will let it write to a shadow file located elsewhere.
But the proper way to get a writeable path shared by all users:
string path = Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData);
I'm surprised it hasn't been mentioned yet, but a viable C# option is to ditch INI files (yuck) and embrace the Settings facilities provided by .Net. They work very well across all Windows versions, they are directly supported by Visual Studio, and finally they are overridable at both the User and Machine level.
We've had no real problems to speak of utilizing this feature (this includes XCopy deployments, Installed applications, Citrix, etc).
Building on the answers of Ben S and akmad, you should put the ini file in the appDataFolder.
If you want the settings to be unique to each user, create an ini file for each user and put it in their AppData folder, which can be retrieved with the following code:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
If you want the settings to be common to all users, but the ini file in the common AppData folder.
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)

Categories