Saving setting to a exe - c#

I have a program which I want to store information in a string. I have been using the Properties.Setting.Default.STRINGname to store the information, which works fine on my PC, and I can see the saved strings (when I go to the settings in the application). But when I take the application to a new PC it losses the strings. Is there a way to be able to edit this information and save it in the app? So basically I need to be able to convert the user setting to application setting, but after the runtime.
var settings = Properties.Settings.Default;
settings.H1 = textbox1.text;
settings.H2 = textbox2.text;
settings.Save();

MSDN explicit says something about this:
Settings that are application-scoped are read-only, and can only be changed at design time or by altering the .config file in between application sessions. Settings that are user-scoped, however, can be written at run time just as you would change any property value. The new value persists for the duration of the application session. You can persist the changes to the settings between application sessions by calling the Save method.
For this, Application setting will never work for you. However, if you are using a User scoped settings it does work, but soon you change the application from one computer to another (as you say you want to) you will loose the settings as that's another machine (another user-scope)...
There are way to continue to have the same settings, you can do, at least 2 things:
use a .config file to save the settings (it's an XML file)
use a service to host the settings and you can read if user has internet access
What you can't do is
using only one executable file, save the settings from computer to computer.

User settings are compiled differently than Application settings, and thus cannot be converted after compilation. Why not compile with Application Settings?

The code you are using should save the user settings. Rememeber that user settings will be saved in the user's data folder. Not in the configuration file where the app was installed (say program files). This is the usual path:
<Profile Directory>\<Company Name>\<App Name>_<Evidence Type>_<Evidence Hash>\<Version>\user.config
See this links form more information

Related

Set value in app.config - no write access to Program Files

I would like to change values in my app.config file (or rather MyProgramName.config file) at runtime. This works fine using
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//update values in config.AppSettings...
config.Save(ConfigurationSaveMode.Modified);
However the MyProgramName.config file is always stored in the program folder according to the documentation (https://msdn.microsoft.com/de-de/library/system.configuration.configurationuserlevel%28v=vs.110%29.aspx)
Application configuration files are in the same directory as the application and have the same name, but with a .config extension. For example, the configuration file for C:\System\Public.exe is C:\System\Public.exe.config.
Now lets assume I have some users who can not write to C:\Program Files(x86)\... (which is the default setting for non-admin users on win7). Is there a way to still use the app.config file properly or maybe place it in the %APPDATA% folder?
You can use the User settings capability of the application settings api for this. These settings are stored in %userprofile%\appdata\local or %userprofile%\Local Settings\Application Data (windows version dependent).
User settings has some limitations: it is, as it says, user specific not global for all users - but presumably if you are updating values at runtime then that's what you want, otherwise you need something like this.
You essentially just have to add a .settings file, which creates the applicationSettings and/or userSettings sections in your app.config (see MSDN: How To: Create a New Setting at Design Time), create your property and set it to User, not Application, and then do this at runtime:
Properties.Settings.Default.myColor = Color.AliceBlue;
Properties.Settings.Default.Save();
The .settings property will create a user settings entry in your app.config that looks like this:
<setting name="Setting1" serializeAs="String" >
<value>My Setting Value</value>
</setting>
You can use this to set the default value that a user session will get before any user-specific value has been saved.
Reference: MSDN: Using Application Settings and User Settings
Data, stored in app.config, are not intended for changing by regular user at run-time. Do not write a code, which re-writes app.config, except the case, when this code is located at some config application for admin. Use application settings instead.

Not able to persist new changes in appsetting section in app.config WPF?

Below is the code i am using to update or change the values in appsetting in app.config
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings["userName"].Value = username;
config.AppSettings.Settings["pwd"].Value = pwd;
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("appSettings");
i am using above code to change or update the settings in appsetting section at runtime and want the changes to persist so that when i run the application it should pick the new values from appsettings but here it doesn't happen so the changes made and saved at run time do not persist when i relaunch my application again it has the old default settings. Also i checked app.config in bin/debug but it too had the old values in appsettings. i refered various blogs and post here too as a reference but it got the same code as above but it did not persist the settings.have referred this post
I had the same problem while ago. I would have preferred to put this in a comment but I don't have that privilege. My answer might not be your case but I think is worth to be shared.
May I ask you where your bin folder is located? Windows 7 when you programmatically alter a file that isn't in a user accessible space creates a copy of that file in a Roaming space and there the file will stay. Every time you try to access the file (like your app.config) W7 transparently redirect your readings/writings to this file, so there's a chance that you are modifying the file in the roaming space, leaving the one you are lookin unaltered.
Are the changes you are making still there the successive time you start the application?
Disclaimer/Apology: I'm not an experienced user so if I am saying silly things let me know and I will remove this comment.
See below(from MSDN) and remember app.config is in your project. .exe.config is the actual file name.
Client applications use a global configuration that applies to all users, separate configurations that apply to individual users, and configurations that apply to roaming users. The userLevel parameter determines the location of the configuration file being opened by indicating whether it has no user level (the configuration file is in the same directory as the application) or has a per-user level (the configuration file is in an application settings path determined by the user level).
Specify which configuration to get by passing one of the following values for userLevel:
To get the Configuration object that applies to all users, set userLevel to None.
To get the local Configuration object that applies to the current user, set userLevel to PerUserRoamingAndLocal.
To get the roaming Configuration object that applies to the current user, set userLevel to PerUserRoaming.
NoteNote
To get the Configuration object for a resource, your code must have read permissions on all the configuration files from which it inherits settings. To update a configuration file, your code must additionally have write permissions for both the configuration file and the directory in which it exists.
i got my solution of above problem, my goal was to persist changes done at run time at application or user level. Initially i tried using App.config where i kept default settings for application in appsettings section of app.config, but later after research i got to refer i got to know appsetting does not persist the changes, instead you can use userSettings section where under YourApplication.Property.Settings you can give your userlevel settings and it worked for me. To do this you do not need to go to App.config to do it manually, rather you can do it from the property window of project.
Right Click on your project -> Select Settings Tab on the left-> Now on the right hand side you will see the Resource section , give the ResourceName, Type, Scope and its value and you are done. The same value can be access and change dynamically from Code as well.
Below are Code Excerpt for the same --
Accessing Settings Value
enter code here
userName = Properties.Settings.Default.UserName;
pwd = Properties.Settings.Default.PWD;
Saving New Settings Back
enter code here
Properties.Settings.Default.UserName = userName.ToString();
Properties.Settings.Default.PWD = newPWD..ToString();
Properties.Settings.Default.Save();
And when you will launch your application next time you will get the new changed settings as your default settings.
I hope that helps
Thanks Guys
VJ

Properties.Settings.Default save to AppData but read from Program Files

When I'm saving settings in context of process runas with specific login and password it's using his home folder (AppData) to store settings. But if I run program in context of the same user from T-SQL Trigger settings file form app_data is not used. There is config file which is used. It's placed in program files with executable. In this config are sections for WCF client settings.
I'm wonder why program doesn't try to read first config file. After manually putting some values to the user section in config when program is running from trigger - he will use them. But for save form single instance it store them in AppData. So after all, when running from trigger in default scenario he reads empty values.
BTW For running program in context of user from trigger I use EXECUTE AS USER = ... exec master..xp_cmdshell ... .
Best Regards

Why are application settings read-only in app.config?

I have some settings in my app.config which I intend to be 'global' - ie. any user can change them, and all users get the same setting.
But unless I change them to be user settings, they are read only.
Why is this?
And how should I go about persisting my app's global settings?
Edit:
This is actually a windows service application which runs as a service as LocalSystem. It can also be run manually by a local admin with argument "/config", which launches a windows form to edit configuration values.
So it will have write access to %PROGRAMFILES% in both situations.
The way I am accessing my settings is thusly:
Settings.Default.MySetting = MyNewValue;
And when MySetting is set to Application (in my project properties, Settings.settings), I get a compile-time error "MySetting is read only".
I am new to this stuff, and have not yet found a very good explanation of how it is supposed to be done. For example, why do I need to say 'Default', and what does that actually mean? I have no idea. If anyone can point me to an app.config usage tutorial, that would be really helpful.
The real complete answer:
The app.config settings are read-only because there are 2 types of settings:
Application Settings
User Settings
The first won't change unless the application publisher publishes a new version of it. The second is not stored in the app.config, but in a user.config file. In the abscence of this user.config file the app.config provides the default value.
If MySetting is a User Setting:
Settings.Default.MySetting = MyNewValue;
Settings.Default.Save();
It will create a user.config file at [User Local Settings Application Data]\[company name]\[application].exe[hash string]\[version] with the new settings, and those settings will prevail over the settings in the app.config file.
Why: Application settings are intended to be stored in the Application folder under Program Files where the user does not have write privileges.
How: There is no default support for "All Users" but you should be able to setup your own custom config file in a public folder or use a Database.
Simply put: There's no location on a machine that everyone can change, unless you give privileges to do so.
There are several ways to deal with this kind of situation:
You can create a configuration file / some registry settings, put this in the "all users" profile and grant "Everyone" the rights to change that specific file. During installation you can automate the procedure for granting the appropiate privileges and your program can handle the rest.
You can leverage UAC to make sure the current user has the appropiate privileges to change a system-wide setting. This is the recommended approach but also means that not everyone can change specific settings.
You can use a shared database and store your settings in there.
???
I would not recommend to change items in the program files directory or changing the default privileges overthere.
EDIT: As local system you have indeed write privileges to the program files directory. If you get the "Read only" error, it means the settings itself are read only. You'll need to use the configuration manager to be able to change the settings in configuration files.
Hope this helps.
One reason is that the app.config file is in your app's folder under the Program Files directory, and everything in Program Files is read only for standard users by default.
Another is that app.config settings apply system wide. If one user makes a change it will impact other users. Normal users are not supposed to be able to make that kind of change. Anything that can impact multiple users should only be set by a system administrator. Per-user settings belong in each user's Application Data folder.
Not quite sure what you mean here.
Do you mean you allowed users to alter app.config from the UI and the changes are not persisted?
did you call
ConfigurationManager.RefreshSection("appSettings");
and
Configuration.Save();
Configuration Settings are cached in the memory when you starts the application. you can deal with the app.config file as xml to change the values.
I'm using this code (a static method) to change the default settings:
public static bool SetGlobalSetting(string settingName, string settingValue)
{
try
{
XmlDocument xml = new XmlDocument();
xml.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
XmlNode xmlNode = xml.DocumentElement.SelectSingleNode("descendant::setting[#name='" + settingName + "']");
xmlNode.SelectSingleNode("value").InnerText = settingValue;
xml.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
Settings s = new Settings();
s.Reload();
return true;
} catch (Exception e)
{
// process the exception as you need
}
return false;
}
}

C# Application can't read/write to files created by administrator when run in limited user account XP

I have an application that is useable by all users (admin or limited) in .NET (C# specifically).
When the application first launches - it creates a few files that it needs in the C:\Documents and Settings\All Users\Documents\ for all subsequent launches.
If the limited user in XP is the FIRST user to launch the application it creates the files fine and both the limited user and administrators can run fine.
However if the Administrator (or I am guessing a different limited user) is the first to launch the application then the limited user is NOT able to run the application.
The two files that it is NOT able to read/write to if created by an Administrator is a Log4Net log file and a SQLite db file.
The SQLite database file is being created with a straitforward .NET File.Copy(sourcepath, destinationpath). The sourcepath is a seed database file installed with the application - so on first run it copies that from the C:\Program Files\app install\seed.db
Is there a way to set the permissions on the file when I copy it? File.SetAccessControl() perhaps? I am not clear on how that works.
The other issue is that the log4Net rolling file appender will not roll the old file and create a new as the old file was created by the admin user when they ran the app.
Any ideas? Ironically this all works perfectly fine in Vista with limited/admin accounts - this is ONLY happening in XP with admin/limited accounts.
I think SetAccessControl is the way to go. Maybe something like this:
// get the existing access controls
FileSecurity fs = File.GetAccessControl(yourFilename);
// add the new rule to the existing settings
fs.AddAccessRule(new FileSystemAccessRule(
#"DOMAIN\Users", // or "BUILTIN\Users", "COMPUTER\AccountName" etc
FileSystemRights.Modify,
AccessControlType.Allow));
// set the updated access controls
File.SetAccessControl(yourFilename, fs);
Note: It's important that you get the existing access control list from the file and then add your new rule to that. If you just create a new access control list from scratch then it will overwrite the existing permissions completely.
Yeah, it's the SetAccessControl method all right, there is a good example here
(the post from satankidneypie)
Good luck

Categories