Application settings reset when exe changes location [duplicate] - c#

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]"

Related

Save user location of toolstrip still not working in VS2012

I've been struggling with multiple toolstrips in a toolstripcontainer for years.
I have a current .NETv3.5 application written in VS2008 where the location of the toolstrips are random. A lot of custom code have been made to fix this but without any luck.
Currently I'm working in VS2012 on a .NETv4.5 application which also has multiple toolstrips.
I created a very small test application that is a form with a docked toolstripcontainer and 4 toolstrips. At design time I added 3 toolstrips to the bottom and 1 to the right.
Without adding any code and starting this application, my toolstrips are located at the same location as in design time. Now I reorder the 3 top toolstrips and restart the application.
My reorder changes are not saved the toolstrips are again as in design time.
Now I add these lines of code:
public partial class Toolstrips : Form
{
private string keyName;
public Toolstrips()
{
this.InitializeComponent();
this.keyName = Application.ProductName + this.Name + "xyz";
ToolStripManager.LoadSettings(this, this.keyName);
}
private void Toolstrips_FormClosing(object sender, FormClosingEventArgs e)
{
ToolStripManager.SaveSettings(this, this.keyName);
}
}
And still in VS2102 with .NETv4.5 this is not working.
I can reorder what I want after restarting the application all toolstrips are restored to the design time locations.
I had hoped this would be fixed in VS2012 but apparently not.
Does anybody have a work around to get this to work?
EDIT: Added contents user.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="System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripTable" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripPan" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripStandard" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripZoom" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripTable>
<setting name="ItemOrder" serializeAs="String">
<value>toolStripButton4</value>
</setting>
<setting name="IsDefault" serializeAs="String">
<value>False</value>
</setting>
<setting name="Size" serializeAs="String">
<value>29, 42</value>
</setting>
<setting name="ToolStripPanelName" serializeAs="String">
<value>toolStripContainer1.Right</value>
</setting>
<setting name="Visible" serializeAs="String">
<value>True</value>
</setting>
<setting name="Location" serializeAs="String">
<value>0, 336</value>
</setting>
<setting name="Name" serializeAs="String">
<value>toolStripTable</value>
</setting>
</System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripTable>
<System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripPan>
<setting name="ItemOrder" serializeAs="String">
<value>toolStripButton3</value>
</setting>
<setting name="IsDefault" serializeAs="String">
<value>False</value>
</setting>
<setting name="Size" serializeAs="String">
<value>40, 31</value>
</setting>
<setting name="ToolStripPanelName" serializeAs="String">
<value>toolStripContainer2.Top</value>
</setting>
<setting name="Visible" serializeAs="String">
<value>False</value>
</setting>
<setting name="Location" serializeAs="String">
<value>288, 0</value>
</setting>
<setting name="Name" serializeAs="String">
<value>toolStripPan</value>
</setting>
</System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripPan>
<System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripStandard>
<setting name="ItemOrder" serializeAs="String">
<value>newToolStripButton,openToolStripButton,saveToolStripButton,printToolStripButton,toolStripSeparator,cutToolStripButton,copyToolStripButton,pasteToolStripButton,toolStripSeparator1,helpToolStripButton</value>
</setting>
<setting name="IsDefault" serializeAs="String">
<value>False</value>
</setting>
<setting name="Size" serializeAs="String">
<value>248, 31</value>
</setting>
<setting name="ToolStripPanelName" serializeAs="String">
<value>toolStripContainer2.Top</value>
</setting>
<setting name="Visible" serializeAs="String">
<value>False</value>
</setting>
<setting name="Location" serializeAs="String">
<value>6, 0</value>
</setting>
<setting name="Name" serializeAs="String">
<value>toolStripStandard</value>
</setting>
</System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripStandard>
<System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripZoom>
<setting name="ItemOrder" serializeAs="String">
<value>toolStripButton1,toolStripButton2</value>
</setting>
<setting name="IsDefault" serializeAs="String">
<value>False</value>
</setting>
<setting name="Size" serializeAs="String">
<value>29, 73</value>
</setting>
<setting name="ToolStripPanelName" serializeAs="String">
<value>toolStripContainer2.Right</value>
</setting>
<setting name="Visible" serializeAs="String">
<value>False</value>
</setting>
<setting name="Location" serializeAs="String">
<value>0, 71</value>
</setting>
<setting name="Name" serializeAs="String">
<value>toolStripZoom</value>
</setting>
</System.Windows.Forms.ToolStripSettings.GUI-prototypeToolstripsxyz.toolStripZoom>
</userSettings>
</configuration>
EDIT2
I've created a small VS2012 application written in C# to illustrate my problem. You can download it here: https://mapwindow5.svn.codeplex.com/svn/tmp/ToolstripDemo/ToolstripDemo.zip
When I start the application I see:
When I reorder the 3 top toolstrips I get this:
Now I close the application and reopen it again, I get the initial locations:
Now I move the toolstrip which was docked at the right to the top:
I reopen the application and I see the 4th toolstrip is still at the top, which is OK but the order is not. Look at the two last toolstrips:
Another strange thing is that I cannot redock my zoom-toolstrip to the right again. The toolstrip just disappears:
When I open my form in VS2012 the toolstrips are rearranged as well:
I'm not sure why. I'm just reopening the form.
I did my testing and made the screenshots by running the exe from the explorer, not in debug-mode of VS.
I hope it is now more clear what I mean and what I need.
Any advice is very much appreciated.
I use vb.net 2010, so I use vb's syntax, but i hope my answer helps:
1) Using ToolStripManager, You can save and load settings without specifying a key for all of toolbars seperately. Specifying a form is enough - settings will be saved for a form using form's name as a key.
2) It is important to call ToolStripManager.SaveSettings() and ToolStripManager.LoadSettings() not prepended by something else programaticaly changing toolbars layout at runtime in FormLoad and FormClosing event-run subroutines. So most safe way to do this, is just call the methods as first in FormClosing and FormLoad subs, as below:
Private Sub Explorer1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ToolStripManager.LoadSettings(Me)'Me is the form, for which we save the toolbars settings
'further code in this subroutine
End Sub
Private Sub Explorer1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
ToolStripManager.SaveSettings(Me)
My.Settings.Save()
'further code in this subroutine
End Sub

Save and reload app.config(applicationSettings) at runtime

I've stored configuration of my application in the app.config, by Visual Studio I've created some application key on the settings tab of project properties dialog, then I've set this key at application level(NOT at user level).
Visual Studio automatically generate the following xml file (app.config) :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="AleTest.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<AleTest.Properties.Settings>
<setting name="DatabasePath" serializeAs="String">
<value>Test.s3db</value>
</setting>
<setting name="DatabaseUser" serializeAs="String">
<value />
</setting>
<setting name="DatabasePass" serializeAs="String">
<value />
</setting>
</AleTest.Properties.Settings>
</applicationSettings>
</configuration>
Now I want to save and reload the settings at runtime, here's my code that allow to save the value DatabasePath in the configuration file:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSectionGroup applicationSectionGroup = config.GetSectionGroup("applicationSettings");
ConfigurationSection applicationConfigSection = applicationSectionGroup.Sections["AleTest.Properties.Settings"];
ClientSettingsSection clientSection = (ClientSettingsSection)applicationConfigSection;
//Database Configuration Setting
SettingElement applicationSetting = clientSection.Settings.Get("DatabasePath");
applicationSetting.Value.ValueXml.InnerXml = this.textBoxPath.Text.Trim();
applicationConfigSection.SectionInformation.ForceSave = true;
config.Save();
The problem is that with this code the new settings aren't loaded by application until I restart the application; is there a way to reload the config settings at runtime?
I also want to replace the fixed value of the name of applicationSettings section (AleTest.Properties.Settings) with a variable value, exist a variable in the framework the assume this value (AleTest.Properties.Settings) ?
You need to make a call to ConfigurationManager.RefreshSection in order to have the values re-read from disk.
I did a some tests and here is result.
For auto generated class Settings the call of ConfigurationManager.RefreshSection("applicationSettings"); doesn't apply the modified values for members marked with ApplicationScopedSettingAttribute, it applies the changes to future calls via ConfigurationManager members (and not sure about UserScopedSettingAttribute).
Instead call Settings.Default.Reload();
What you want is accomplish able by creating an custom ConfigSection which allows you more control and allows you to change the name. Configuration manager has a refresh section which will allow you reload the data.
Aleroot's code for updating values worked fine.
In spite of Properties.Settings being write only (no set).
To refresh, this worked for me:
ConfigurationManager.RefreshSection("applicationSettings");
But I'm using this to access the parameter:
string test = Properties.Settings.Default.MyString;
MessageBox.Show("Paramètres/Settings MyString = " + test);

C# - Compiler Error: System.Configuration.ConfigurationErrorsException was unhandled

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

web.release.config change dynamic webservice url

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.

ConfigurationManager.AppSettings[key] is always null

I am trying to get the value for the key "sUser" in appSetting section from app.config
this is the code on my class.cs
string sUsr = ConfigurationManager.AppSettings.Get["sUser"];
But always its null.
I try this code (I took it from MSDN):
// Get the configuration file.
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Get the appSettings section.
AppSettingsSection appSettings = (AppSettingsSection)config.GetSection("appSettings");
// Get the auxiliary file name.
Console.WriteLine("Auxiliary file: {0}", config.AppSettings.File);
But it shows that the file Empty
Also I am using the stting console to write those properties and it works if I get the apps using
string sUsr = WIW.Business.Properties.Settings.Default.sUser;
But I am going to use that class as a reference in a website and on the web.config of the site I can't configure those settings
In your App.config the appSettings section should look like the following:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="sUser" value="Test"/>
</appSettings>
</configuration>
use Properties.Settings.Default.{your_setting_key} to access the value
I.E
Properties.Settings.Default.sPassword return 8909039388
All these were included in Properties Class.
I had the same problem. I was calling another project(In the same solution) and was expecting the appSettings to be present.
To make it work,I added the following lines in the application that was calling the target application.
<appSettings>
<add key="sUser" value="Test"/>
</appSettings>
It worked for me after that. Try this. It might help you too
Here its my app.config, if I try to get the key values from the appSettings sections I always get null, but If I try to get them from applicationsection Its no problem, the thing is that I need put that applicationsection on a web site but on a web site i can put applicationSettings
<configuration>
<appSettings>
<add key="sUser" value="userbancolombia">
<add key="sPassword" value="8909039388">
<appSettings>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="WIW.Business.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<system.serviceModel>
<bindings />
<client />
</system.serviceModel>
<applicationSettings>
<WIW.Business.Properties.Settings>
<setting name="WIW_Business_WsCCMain_ConsultaNuips" serializeAs="String">
<value>http://coomeva1/AsisaWS_2008/ConsultaNuips.asmx</value>
</setting>
<setting name="WIW_Business_WsCCAux_ConsultaNuips" serializeAs="String">
<value>http://coomeva1/AsisaWS_2008_Sec/ConsultaNuips.asmx</value>
</setting>
<setting name="WIW_Business_WsCEMain_ConsultaCedulaExtranjeria"
serializeAs="String">
<value>http://coomeva1/AsisaWS_2008/ConsultaCedulaExtranjeria.asmx</value>
</setting>
<setting name="WIW_Business_WsCEAux_ConsultaCedulaExtranjeria"
serializeAs="String">
<value>http://coomeva1/AsisaWS_2008_Sec/ConsultaCedulaExtranjeria.asmx</value>
</setting>
<setting name="sUser" serializeAs="String">
<value>userbancolombia</value>
</setting>
<setting name="sPassword" serializeAs="String">
<value>8909039388</value>
</setting>
</WIW.Business.Properties.Settings>
</applicationSettings>
</configuration>

Categories