Windows Service ignores configuration file completely - c#

The problem is that whatever I put in the config file (Service1.exe.config) or even delete it - Windows Service simply doesn't care, it still pulls data from somewhere. I also noticed when I was searching for a value in files (searching for a string), I found it in the exe file of the service!? How is this possible? What can I do to change this behaviour?
Thanks
SMARTService.Properties.Settings propRemote;
SMARTService.LocalSettings propLocal;
SMARTService.smtp propSmtp;
protected override void OnStart(string[] args)
{
propRemote = SMARTService.Properties.Settings.Default;
propLocal = SMARTService.LocalSettings.Default;
propSmtp = SMARTService.smtp.Default;
}
And later I used them throughout code.
The settings file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="SMARTService.smtp" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="SMARTService.LocalSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="SMARTService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<applicationSettings>
<SMARTService.smtp>
....
</SMARTService.smtp>
<SMARTService.LocalSettings>
....
</SMARTService.LocalSettings>
<SMARTService.Properties.Settings>
....
</SMARTService.Properties.Settings>
</applicationSettings>
</configuration>

Related

How to pass on app.config settings of a DLL through a xUnit testserver.dll.config?

I have the following code structure:
xUnit tests
These use features from my.dll
The my.dll uses a third party logger.dll
If I use the my.dll outside of xUnit's testserver.dll, then I can just add a my.dll.config with the following contents:
<?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="Thirdparty.Logger.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</sectionGroup>
</configSections>
<assemblySettings>
<add key="Hostname" value="127.0.0.1"/>
<add key="Port" value="1234"/>
</assemblySettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<applicationSettings>
<Thirdparty.Logger.Properties.Settings>
<setting name="LogPath" serializeAs="String">
<value>C:\log\dir</value>
</setting>
</Thirdparty.Logger.Properties.Settings>
</applicationSettings>
</configuration>
And within my.dll's constructor, I can read them like follows, which works just fine.
AssemblySettings settings = new AssemblySettings();
var host = settings["Hostname"];
var port = settings["Port"];
Also the LogPath is passed on to logger.dll, which is closed source to me, but the logger.dll can definitely read the value passed on as LogPath.
Now, I have been successfully able to pass on the logger.dll's settings through xUnit as well using a testserver.dll.config file, which looks like follows:
<?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="Thirdparty.Logger.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
<section name="MyDll.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<applicationSettings>
<Thirdparty.Logger.Properties.Settings>
<setting name="LogPath" serializeAs="String">
<value>C:\log\dir</value>
</setting>
</Thirdparty.Logger.Properties.Settings>
<MyDll.Properties.Settings>
<setting name="Hostname" serializeAs="String">
<value>127.0.0.1</value>
</setting>
<setting name="Port" serializeAs="String">
<value>1234</value>
</setting>
</MyDll.Properties.Settings>
</applicationSettings>
</configuration>
And also in this case, the LogPath is successfully passed on, but the settings for my.dll.config are not. The AssemblySettings instance is null:
AssemblySettings settings = new AssemblySettings();
// settings == null
What am I doing wrong?
Assembly.GetCallingAssembly().FullName in the constructor of AssemblySettings evaluates to "MyDll, Version=6.1.0.0, Culture=neutral, PublicKeyToken=null", but the returned instance is null.

Accessing Settings in different ways

I have a new (test) console application that I'm trying to access the settings.
When I attempt to access it this way, from what I've read on SO and other places, this should work:
var test1 = System.Configuration.ConfigurationManager.AppSettings["MySetting"];
but it doesn't, it returns null.
When I do it this way, it works fine:
var test2 = Properties.Settings.Default.MySetting;
Why doesn't the first one work? Everything I've read shows to use it the first way.
Am I using it incorrectly?
EDIT
In response to Mason.
I'm confused on your comment. The app.config is where the setting is being set from the properties of the application:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ConsoleApp1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<applicationSettings>
<ConsoleApp1.Properties.Settings>
<setting name="MySetting" serializeAs="String">
<value>testtesttest</value>
</setting>
</ConsoleApp1.Properties.Settings>
</applicationSettings>
</configuration>
System.Configuration.ConfigurationManager.AppSettings is for reading settings from the app.config or web.config files (for ASP.NET). It does not read from the settings files.
Because AppSettings refers to reading the settings in MyApp.config

Which App.config is current?

I'm running Visual Studio 12.0 targeting 4.5. I'm running VS Express. My App.config looks like this:
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ConfigMgrTest2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<applicationSettings>
<ConfigMgrTest2.Properties.Settings>
<setting name="exampleAppSetting" serializeAs="String">
<value>example app setting data</value>
</setting>
</ConfigMgrTest2.Properties.Settings>
</applicationSettings>
</configuration>
This allows me to use this syntax to access values:
string value = ConfigMgrTest2.Properties.Default.exampleAppSetting;
It seems from my research that I should have an "appSettings" section in my App.config that uses key-value pairs and looks like this:
<appSettings>
<add key="exampleAppSetting" value="example app setting data"/>
</appSettings>
This would allow me to access values like this:
string key = "exampleAppSetting";
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
string value = appSettings[key];
Using my App.config, any call to the ConfigurationManager.AppSettings property is obviously returning null.
The question is, Which version of App.config is "right"?
Both are right and current.
In your example,
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ConfigMgrTest2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
You have simply used System.Configuration.ApplicationSettingsGroup to define a new configuration group applicationSettings.
if you were to add this to your config file:
<appSettings>
<add key="Alfa" value="42"/>
</appSettings>
You could still retrieve it with:
var alfa = ConfigurationManager.AppSettings["Alfa"];
Update
Full App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ConfigMgrTest2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<applicationSettings>
<ConfigMgrTest2.Properties.Settings>
<setting name="exampleAppSetting" serializeAs="String">
<value>example app setting data</value>
</setting>
</ConfigMgrTest2.Properties.Settings>
</applicationSettings>
<appSettings>
<add key="Alfa" value="42"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Personally, I prefer custom configurations, since they allow me to provide for default values, as well as make some mandatory.
I am not sure about which version is proper, which may depend on your actual usage scenario but if you have the posted section in your app.config like below
<appSettings>
<add key="exampleAppSetting" value="example app setting data"/>
</appSettings>
Then you need to access it like below. You need to mention the KEY for which you are trying to get the value.
ConfigurationManager.AppSettings["exampleAppSetting"]
Assuming you have created a desktop application (WinForms or WPF) the App.config file is automatically copied to the output folder alongside with the executable and renamed to YourApplication.exe.config. It is inside this file that you could have the <appSettings> section:
<configuration>
<appSettings>
<add key="exampleAppSetting" value="example app setting data"/>
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
and then you will be able to access this value like this:
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
string value = appSettings["exampleAppSetting"];
You might prefer using custom configuration sections when you have some complex config properties. In this case it might make more sense to move them in a separate configuration file and write a custom section.

How to save value for key in *config file

Try to store and to read some user definde value to *.config file
Code for reading from file
public int GetVolumeFromConfigFile()
{
return Convert.ToInt32(ConfigurationManager.AppSettings["Volume"]);
}
Works perfect
Try to update existing key with this
public int SetVolumeFromConfigFile()
{
ConfigurationManager.AppSettings["Volume"] = "10";
}
Got error - file only for reading, change for something like this:
Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
config.AppSettings.Settings.Add(label.Text.ToString(), box.Value.ToString());
config.Save(ConfigurationSaveMode.Minimal);
Got no errors, but nothing changed in file.
My *.config file is :
<?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="PlayDemo.SettingsPlayIt" 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" />
</startup>
<userSettings>
<PlayDemo.SettingsPlayIt>
<setting name="Volume" serializeAs="String">
</setting>
</PlayDemo.SettingsPlayIt>
</userSettings>
Just try to understand where I'm wrong
Here it is
Configuration config = ConfigurationManager.OpenExeConfiguration(System.Windows.Forms.Application.ExecutablePath);
config.AppSettings.Settings["Volume"].Value = "10";
config.Save(ConfigurationSaveMode.Modified);
This won't update the App.config in your project in Visual Studio, but the "ExecutableName".config in the bin folder of your project.

Restore Application Settings after restarting the application

I have a C# application where I store certain value in a Settings file like this:
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="VITRIconEvacuationPlan.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
</sectionGroup>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="VITRIconEvacuationPlan.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<EvacuationPlan.Properties.Settings>
<setting name="AssemblyCentre" serializeAs="String">
<value>False</value>
</setting>
</EvacuationPlan.Properties.Settings>
</applicationSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup><userSettings>
<EvacuationPlan.Properties.Settings>
<setting name="SymbolScale" serializeAs="String">
<value>25</value>
</setting>
</EvacuationPlan.Properties.Settings>
</userSettings>
</configuration>
Per default, the SymbolScale property is set to 25 (when I start the application the first time)
I want to change the SymbolScale property at runtime so I put this into User Scope. So I can say:
setting.SymbolScale = 150;
setting.save();
But when I close my application the value of the SymbolScale is 25 again. But I want it to store my chenged value from the runtime. What am I doing wrong?
I found a solution here:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/ddeaca86-a093-4997-82c9-01bc0c630138/
I just had to change and save my SymbolValue like that:
Properties.Settings.Default.SymbolScale = 150;
Properties.Settings.Default.Save();
Properties.Settings.Default.Upgrade();
Properties.Settings.Default.Save();
I am not sure why I have to call the save function two times but it works (And only with calling it two times)
Are you sure that you are checking the right "user.config" file?
At usual that stored in "C:\Users\xyzuser\AppData\Local\yourcompany\youarpp\version\user.config".
Hope that helps!
Set it like: Settings.Default.SymbolScale = 150;
Save it with Settings.Default.Save();

Categories