I have a ruleList in my form, I want to save every item in it and load the values when i start the application again.
So I created a new settings tab in Properties -> Settings
Edited Settings.settings file like this :
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="fireWall.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="Location" Type="System.Drawing.Point" Scope="User">
<Value Profile="(Default)">50, 50</Value>
</Setting>
<Setting Name="FormSize" Type="System.Drawing.Size" Scope="User">
<Value Profile="(Default)">800, 600</Value>
</Setting>
<Setting Name="FirewallList" Type="System.Collections.Generic.List<NetFwTypeLib.INetFwRule2>" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="myTestDataList" Type="System.Collections.Generic.List<System.String>" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>
and finally I saved my list on FormClosing : Properties.Settings.Default["FirewallList"] = RuleList;
However when I try to load my rules from user settings
RuleList = Properties.Settings.Default["FirewallList"] as List<INetFwRule2>;
I get a null exception error.
My Closing Form :
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// saving windows size and location
Properties.Settings.Default.FormSize = this.Size;
Properties.Settings.Default.Location = this.Location;
// saving RuleList
Properties.Settings.Default["FirewallList"] = RuleList;
// saving list of random Strings
Properties.Settings.Default.myTestDataList = new List<String>();
Properties.Settings.Default.myTestDataList.Add("stack");
Properties.Settings.Default.myTestDataList.Add("overflow");
Properties.Settings.Default.myTestDataList.Add(".com");
// saving all settings
Properties.Settings.Default.Save();
}
PS : Am I doing right saving a list to user settings? Would a custom .txt file for example be suitable for my situation?
Using settings at runtime. Take a look at MSDN here:
Access the user setting and assign it a new value, as shown in the following example:
Properties.Settings.Default.myColor = Color.AliceBlue;
If you want to persist changes to user settings between application sessions, call the Save method, as shown in the following code:
Properties.Settings.Default.Save();
Related
I am updating one setting in my config file on button click. The code i found is easy to understand and I am sure it works that way. But the problem lies with either updating the section in my config file or writing to it.
So on button click it goes through this method:
private static void UpdateSetting(string key, string value)
{
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
configuration.AppSettings.Settings[key].Value = value;
configuration.Save();
ConfigurationManager.RefreshSection("applicationSettings");
}
And this is the targetet section in my config file:
<applicationSettings>
<UpdatePackager.Properties.Settings>
<setting name="Sourcepath" serializeAs="String">
<value>D:\PMSmart</value>
</setting>
<setting name="DestinationpathUpdatePackages" serializeAs="String">
<value>D:\xxx</value>
</setting>
<setting name="DestinationpathClient" serializeAs="String">
<value>D:\xxx</value>
</setting>
<setting name="Versions" serializeAs="String">
<value>v5_9_0/v5_9_1/v5_9_2</value>
</setting>
</UpdatePackager.Properties.Settings>
</applicationSettings>
Am i missing something or doing something the wrong way?
It is the .config file in the output directory of your .exe that should get updated, and not the one in your project folder.
When you build the application and run it again, the modified config file will be overwritten by the one in your project folder.
Check the value in the .config file in the bin/Debug or bin/Release folder during runtime and you should see that it has been updated after your UpdateSetting method has been executed.
I'm writing an application with Windows Forms, .NET 4.6, using a bunch of settings configurable in run-time. Modifying, adding and deleting settings works fine within one run, but all changes are lost when the app closes. I do use Properties.Settings.Default.Save() just before the main window closes:
private void TestersList_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.Save();
}
A user.config file is created as expected in AppData, but only one of the settings is saved there, no matter what I do with it or any other setting in run time.
All of the settings are defined in user scope and serialized as strings. I see nothing that makes the one that is saved any different from the others.
Below is a part of app.config:
<userSettings>
<DailyChecklist.Properties.Settings>
<setting name="SerialPattern2" serializeAs="String">
<value>\d{10}_0_None</value>
</setting>
</setting>
<setting name="SerialPatternDebug" serializeAs="String">
<value>123456789</value>
</setting>
<setting name="TestersToIgnore" serializeAs="String">
<value>dummy;</value>
</setting>
<setting name="SerialPatternDefault" serializeAs="String">
<value>\D\d]{3}\D{2,3}\d{4}\d{5}</value>
</setting>
<setting name="ServerAdress" serializeAs="String">
<value>address/goes/here</value>
</setting>
</DailyChecklist.Properties.Settings>
</userSettings>
And after saving I got this in user.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<DailyChecklist.Properties.Settings>
<setting name="TestersToIgnore" serializeAs="String">
<value>dummy;</value>
</setting>
</DailyChecklist.Properties.Settings>
</userSettings>
</configuration>
How can I make it save all settings in user.config?
Thanks in advance!
PS. I have checked that it's not the scope, I have no '*' in assembly info and the file I was monitoring is the only file created (no version/build number changes). It gets modified (according to notepad++) and if I change TestersToIgnore, its new value is saved, but all other settings are missing.
Well, I figured it out finally, so I'm leaving it here for future unfortunate souls.
The magical word is: foreach.
Although it is possible to iterate through Properties.Settings.Default.Properties in a foreach loop, changes are temporary. I mean solution like:
foreach(SettingsProperty setting in Properties.Settings.Default.Properties)
{
if(setting.Name.Contains("someKeyWord"))
Properties.Settings.Default[setting.Name] = someNewSettingValue;
}
seems to be working within current run, but changes are lost after restart. Properties.Settings.Default.Save() for some reason won't save anything that was changed from within a loop.
I checked and Properties.Settings.Default[setting.Name] = someNewSettingValue; works just fine outside of a loop and is normally saved then.
If you need dynamically added settings, consider using a single setting configured as one of System.Collections.Specialized types. It might make your code less transparent, but at least it handles loops well.
This question already has answers here:
Settings.settings File Keeps Getting Reset
(4 answers)
Closed 6 years ago.
Hi I'm using the Visual Studio config files, however the settings change every time I move the exe.
How can I fix this?
app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="GUIChangerUI.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<userSettings>
<GUIChangerUI.Properties.Settings>
<setting name="StarmadePath" serializeAs="String">
<value>default</value>
</setting>
<setting name="GuiPath" serializeAs="String">
<value>Not selected yet.</value>
</setting>
<setting name="FirstStart" serializeAs="String">
<value>True</value>
</setting>
<setting name="jpeg" serializeAs="String">
<value>default</value>
</setting>
<setting name="debug" serializeAs="String">
<value>default</value>
</setting>
<setting name="Darktheme" serializeAs="String">
<value>False</value>
</setting>
<setting name="Lightheme" serializeAs="String">
<value>True</value>
</setting>
<setting name="starmadeStarter" serializeAs="String">
<value />
</setting>
<setting name="_starmadeStarter" serializeAs="String">
<value />
</setting>
<setting name="OSMTheme" serializeAs="String">
<value>False</value>
</setting>
</GUIChangerUI.Properties.Settings>
</userSettings>
</configuration>
The actual configuration file containing saved configuration settings is stored here:
%APPDATA%\Local\<application name>\<application name>.<eid>_<hash>\<version>
According to this MSDN article::
<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.
(my emphasis)
So the solution seems simple:
Create a strong name and sign your executable.
Then you will get the same unique hash every time and it won't change whenever you start the executable from a new location.
If you need help signing your application, please refer to this MSDN article: How to: Sign an Assembly with a Strong Name.
The user settings will be stored in your user's profile in such a way that the location of your application is linked. That's why the application, when moved, does not find the settings anymore.
What you can try to do is:
Create a new user setting named SettingsUpgradeRequired and set it to true in the settings designer in Visual Studio.
In your application's startup code, check whether SettingsUpgradeRequired is true and if so, perform a settings upgrade.
As the new setting will only be true after the settings file was reset, the following should import the old settings, and it should do so only once:
if (Properties.Settings.Default.SettingsUpgradeRequired)
{
try
{
Properties.Settings.Default.Upgrade();
Properties.Settings.Default.SettingsUpgradeRequired = false;
Properties.Settings.Default.Save();
}
catch (...)
{
... // Upgrade failed - tell the user or whatever
}
}
That behavior is by design because you could have multiple versions of you application (for instance a QA version, a PROD version and so on) that requires different setting storages. See also Client Settings FAQ for details.
If you need a settings management that is independend of the location / version of you app, i would suggest wo create your own settings file and store them below "%appdata%[company][application]"
Hey Everyone,
How do I fix the Compiler Error upon compiling on "return ((string)(this["TargetDir"]));":
System.Configuration.ConfigurationErrorsException was unhandled
Configuration system failed to initialize
{"Unrecognized configuration section userSettings/CCP.Settings1. (C:\\Users\\bmccarthy\\Documents\\Visual Studio 2008\\Projects\\CCP Utility\\CCP Utility\\bin\\Debug\\CCP_Utility.exe.config line 21)"}
A first chance exception of type 'System.Configuration.ConfigurationErrorsException' occurred in System.Configuration.dll
Here's the code in my Settings.Designer.cs file under the Properties directory:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string TargetDir {
get {
return ((string)(this["TargetDir"]));
}
set {
this["TargetDir"] = value;
}
}
Here's the code for CCP_Utility.exe.config from the bin folder:
<CCP_Utility.Properties.Settings>
<setting name="SourceDir" serializeAs="String">
<value />
</setting>
<setting name="TargetDir" serializeAs="String">
<value />
</setting>
<setting name="CorpID" serializeAs="String">
<value />
</setting>
</CCP_Utility.Properties.Settings>
<CCP_Utility.Settings1>
<setting name="sourceDir" serializeAs="String">
<value />
</setting>
<setting name="targetDir" serializeAs="String">
<value />
</setting>
</CCP_Utility.Settings1>
What does the < CCP_Utility.Settings1 > tag have to match up to?? App.config and what else?
Does capitalization matter? I have the variable declared as TargetDir Settings.Settings....
Where is the System.Configuration.dll file located?
I got the application to compile without compiler errors by changing the capitilzation of sourceDir and targetDir under CCP_Utility.Settings1 in the Settings1.Designer.cs file as follows:
<CCP_Utility.Settings1>
<setting name="SourceDir" serializeAs="String">
<value />
</setting>
<setting name="TargetDir" serializeAs="String">
<value />
</setting>
</CCP_Utility.Settings1>
Verify UserScopedSettingAttribute matches up with the correct settings section.
If I remember correct, yes, case-sensitive.
Usually, I will add a setting, save and close, then open the settings designer again, and delete the setting, save and close. This will get the designer in-sync. I have seen them get out-of-sync the first time the designer is opened on a computer. (For example, when you get from source control.)
I'm editing my web.release.config file for production. I want the web.config file changed after a publish.
I found how to change the web.config by using the web.release.config file properly, but not for this particular component.
The URL of an dynamic webservice has to change.
In the web.config:
<applicationSettings>
<FooService.Properties.Settings>
<setting name="FooService_Student" serializeAs="String">
<value>http://testwebservices.foo.bar.nl/Student.asmx</value>
</setting>
<setting name="FooService_User" serializeAs="String">
<value>http://testwebservices.foo.bar.nl/User.asmx</value>
</setting>
</FooService.Properties.Settings>
</applicationSettings>
now, how do I change the <value> in both settings? I tried the following, but that didn't work out:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<applicationSettings>
<FooService.Properties.Settings>
<setting name="FooService_Student" serializeAs="String" xdt:Transform="Replace">
<value>http://webservices.foo.bar.nl/Student.asmx</value>
</setting>
<setting name="FooService_User" serializeAs="String" xdt:Transform="Replace">
<value>http://webservices.foo.bar.nl/User.asmx</value>
</setting>
</FooService.Properties.Settings>
</applicationSettings>
</configuration>
Anyone experience with this matter?
Thankyou!
Add xdt:Transform="Replace" to the applicationSettings tag.
<applicationSettings xdt:Transform="Replace">
<FooService.Properties.Settings>
<setting name="FooService_Student" serializeAs="String">
<value>http://webservices.foo.bar.nl/Student.asmx</value>
</setting>
<setting name="FooService_User" serializeAs="String">
<value>http://webservices.foo.bar.nl/User.asmx</value>
</setting>
</FooService.Properties.Settings>
How about adding a xdt:Locator="Match(name)", that will probably be what you need to find the exact nodes to replace.