Unrecognized configuration section userSettings but Debug works fine - c#

My app is working fine when debugging but when I'm trying to run it outside visual studio it just keeps crashing and all what I can find is this in event viewer:
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Configuration.ConfigurationErrorsException
at System.Configuration.ConfigurationSchemaErrors.ThrowIfErrors(Boolean)
at System.Configuration.BaseConfigurationRecord.ThrowIfParseErrors(System.Configuration.ConfigurationSchemaErrors)
at System.Configuration.BaseConfigurationRecord.ThrowIfInitErrors()
at System.Configuration.ClientConfigurationSystem.OnConfigRemoved(System.Object, System.Configuration.Internal.InternalConfigEventArgs)
Exception Info: System.Configuration.ConfigurationErrorsException
at System.Configuration.ConfigurationManager.PrepareConfigSystem()
at System.Configuration.ConfigurationManager.RefreshSection(System.String)
at System.Configuration.ClientSettingsStore.ReadSettings(System.String, Boolean)
at System.Configuration.LocalFileSettingsProvider.GetPropertyValues(System.Configuration.SettingsContext, System.Configuration.SettingsPropertyCollection)
at System.Configuration.SettingsBase.GetPropertiesFromProvider(System.Configuration.SettingsProvider)
at System.Configuration.SettingsBase.GetPropertyValueByName(System.String)
at System.Configuration.SettingsBase.get_Item(System.String)
at System.Configuration.ApplicationSettingsBase.GetPropertyValue(System.String)
at System.Configuration.ApplicationSettingsBase.get_Item(System.String)
at LeagueFPSBoost.Properties.Settings.get_UpgradeRequired()
at LeagueFPSBoost.Program.CreateConfigIfNotExists()
at LeagueFPSBoost.Program.Startup(System.String[])
at LeagueFPSBoost.Program.Main(System.String[])
It was working fine, i just dont know what happened to it. Here is more info:
static void CreateConfigIfNotExists()
{
var configFile = $"{Application.ExecutablePath}.config";
if (!File.Exists(configFile))
{
File.WriteAllText(configFile, Resources.App_Config);
}
var configDir = Path.Combine(leagueConfigDirPath, #"LeagueFPSBoost\");
if (!Directory.Exists(configDir))
{
Directory.CreateDirectory(configDir);
}
if (!File.Exists(Path.Combine(configDir, "App.config")))
{
File.WriteAllText(Path.Combine(configDir, "App.config"), Resources.App_Config);
}
AppConfig.Change(Path.Combine(configDir, "App.config"));
if (File.Exists(configFile))
{
File.Delete(configFile);
}
if (Settings.Default.UpgradeRequired) //Exception Thrown Here
{
Settings.Default.Upgrade();
Settings.Default.UpgradeRequired = false;
Settings.Default.Save();
}
}
And this is from Settings.Desinger.cs:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool UpgradeRequired {
get {
return ((bool)(this["UpgradeRequired"]));
}
set {
this["UpgradeRequired"] = value;
}
}
Here is App.config:
<?xml version="1.0" encoding="utf-8"?>
<!-- User settings like theme and etc are stored in ...\AppData\Local\LeagueFPSBoost\... -->
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="LeagueFPSBoost.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" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<userSettings>
<LeagueFPSBoost.Properties.Settings>
<setting name="ThemeStyle" serializeAs="String">
<value>Light</value>
</setting>
<setting name="ColorStyle" serializeAs="String">
<value>Blue</value>
</setting>
<setting name="Notifications" serializeAs="String">
<value>True</value>
</setting>
<setting name="Log" serializeAs="String">
<value>True</value>
</setting>
<setting name="UpgradeRequired" serializeAs="String">
<value>True</value>
</setting>
</LeagueFPSBoost.Properties.Settings>
</userSettings>
</configuration>
When application starts from Visual Studio in debug mode everything works fine every time. Problem is when I run application by clicking on exe it works first time (if user.config doesn't exist in roaming/local/appname.. folder). One I run application for second time by clicking on exe I just get the same error every time. But when I delete user.config file it starts again normally but it just wont start with user.config being there....
This is user.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<LeagueFPSBoost.Properties.Settings>
<setting name="ThemeStyle" serializeAs="String">
<value>Dark</value>
</setting>
<setting name="ColorStyle" serializeAs="String">
<value>Red</value>
</setting>
<setting name="Notifications" serializeAs="String">
<value>True</value>
</setting>
<setting name="Log" serializeAs="String">
<value>True</value>
</setting>
<setting name="UpgradeRequired" serializeAs="String">
<value>False</value>
</setting>
</LeagueFPSBoost.Properties.Settings>
</userSettings>
</configuration>
Sometimes I'm also getting this exception:
System.Configuration.ConfigurationErrorsException: Unrecognized configuration section userSettings
(C:\Users\...\AppData\Local\LeagueFPSBoost\LeagueFPSBoost.exe_Url_10kxs4....xzo1\2.8.0.0\user.config line 3)
I tried incrementing 2.8.0.0 to 2.9.0.0 but I still got same problem.
It was working fine before, I don't know what happened to it.
Edit: I found out where exception is thrown by attacking debugger to process but still I don't know why?
Edit 2: I found out that adding:
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="LeagueFPSBoost.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
to the user.config fixes the problem but why is it missing in there in first place?

I've found answer here.
I have modified a code a bit so that its universal:
/// <summary>
/// Corrects the roaming settings file if needed because sometimes the node "configSections" is missing in the settings file.
/// Correct this by taking this node out of the default config file.
/// </summary>
private static void CorrectRoamingSettingsFileIfNeeded()
{
const string NODE_NAME_CONFIGURATION = "configuration";
const string NODE_NAME_CONFIGSECTIONS = "configSections";
const string NODE_NAME_USERSETTINGS = "userSettings";
//Exit if no romaing config (file) to correct...
var configRoaming = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
if (configRoaming == null) return;
if (!configRoaming.HasFile) return;
//Check for the <sectionGroup> with name="userSettings"
//Note: Used ugly iteration because "configRoaming.GetSectionGroup(sectionGroupName)" throws ArgumentException.
ConfigurationSectionGroup sectionGroupUserSettings = null;
foreach (ConfigurationSectionGroup sectionGroup in configRoaming.SectionGroups)
{
if (sectionGroup.Name.Equals(NODE_NAME_USERSETTINGS))
{
sectionGroupUserSettings = sectionGroup;
break;
}
}
//Exit if the needed section group is found...
if (sectionGroupUserSettings != null && sectionGroupUserSettings.IsDeclared) return;
//Do correction actions...
var xDoc = XDocument.Load(configRoaming.FilePath);
var userSettingsNode = xDoc.Element(NODE_NAME_CONFIGURATION).Element(NODE_NAME_USERSETTINGS);
var ConfigFullFilename = Assembly.GetEntryAssembly().Location;
var configDefault = ConfigurationManager.OpenExeConfiguration(ConfigFullFilename);
var xDocDefault = XDocument.Load(configDefault.FilePath);
var configSectionsNode = xDocDefault.Element(NODE_NAME_CONFIGURATION).Element(NODE_NAME_CONFIGSECTIONS);
userSettingsNode.AddBeforeSelf(configSectionsNode);
xDoc.Save(configRoaming.FilePath);
}
That was confusing as hell....

While this is not directly related to the OP, this is the post users are sent to when searching for this error, so it is worth pointing out here as it is related.
This error occurs in .Net Core when adding an app.config using system.Configuration.ConfigurationManager 4.7.0:
ConfigurationErrorsException: Unrecognized configuration section add. (C:\Source\Repos\SFTP_Application\SFTP_Application\SFTP_Application_Console\bin\Debug\netcoreapp3.1\SFTP_Application_Console.dll.config line 3)
Unrecognized configuration section add means: it is missing a "section" and it thinks that <add> is a section.
In .Net Core's case, it is originally built to run off .json, but not everyone likes running their site off .json alone. So, you can add a .config file, but out of the box that file is missing an <appSettings> section. Put your keys in that, and your good to go.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ApplicationId" value="0" />
<!--SqlConnections-->
<add key="sql_Con_String" value="mydsstring" />
</appSettings>
</configuration>

Related

How to get ApplicationSettings in a class library for winform?

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="MyApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<MyApp.Properties.Settings>
<setting name="ShortDateFormat" serializeAs="String">
<value>dd/MM/yyyy</value>
</setting>
<setting name="ShortDateFormatWithPeriod" serializeAs="String">
<value>dd.MM.yyyy</value>
</setting>
<setting name="TimeFormat24Hour" serializeAs="String">
<value>HH:mm</value>
</setting>
<setting name="TimeFormat24HourWithSecond" serializeAs="String">
<value>HH:mm:ss</value>
</setting>
<setting name="TimeSpanFormat" serializeAs="String">
<value>hh\:mm</value>
</setting>
<setting name="TimeSpanFormatWithSecond" serializeAs="String">
<value>hh\:mm\:ss</value>
</setting>
</MyApp.Properties.Settings>
</applicationSettings>
</configuration>
I have this app.config file. I would like to get value of ShortDateFormat from it in a class library. I understand ConfigurationManager is the way to do it. But after many failed attempts I have begun to wonder if it's even possible.
Here's what I have tried so far:
var conf = ConfigurationManager.GetSection("applicationSettings");
=> returns null
var conf = ConfigurationManager.GetSection("MyApp.Properties.Settings");
=> returns null
The following block of code gives me the section. But I don't see anything in the section that would give me the value of the property.
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var sectionGroup = config.GetSectionGroup("applicationSettings");
var section = sectionGroup.Sections["MyApp.Properties.Settings"];
So am I missing anything? Is there a way to get the value for "ShortDateFormat" and other properties?
you can get like AppSetting["PropertyName"].ToString();
else
you can create property file under Resources and set all the Property and create one Model with Property where you can use get;set; for each Property.

How to match xml node of Settings file in C# application

My C# code is below.
<?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="ICTRExchange.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.6.1" />
</startup>
<userSettings>
<ICTRExchange.Properties.Settings>
<setting name="ServerIP" serializeAs="String">
<value />
</setting>
<setting name="ServerPort" serializeAs="String">
<value>0</value>
</setting>
How to match using regular expression in C#.
I try regular expression in below. but It is not proper operation.
example
My target node is "ServerPort"
var regex = new Regex("<setting name=\"ServerPort\"(.*?)</setting>");
regex.match(xmlstring)
Parsing mark up alnguage with regex is very bad idea (see: Using regular expressions to parse HTML: why not? - it's aboout HTML, but also applies to XML).
Instead, you could use XML library provided in .NET, like System.Xml.
Here's code snippet you could build your application on (I stored your XML in testxml.xml file):
static void Main(string[] args)
{
XmlDocument xml = new XmlDocument();
xml.Load(#"C:/users/MyUser/desktop/testxml.xml");
var settings = xml.SelectNodes("configuration/userSettings/ICTRExchange.Properties.Settings")[0].ChildNodes;
XmlNode settingsWithServerPort = null;
foreach (XmlNode node in settings)
if (node.Attributes["name"].Value == "ServerPort")
settingsWithServerPort = node;
}
You can try this
<setting.*?>[\w\W]+?<\/setting>
Explanation
<setting.*?> - Matches <setting followed by anything except new line followed by >.
[\w\W]+? - Matches anything one or more time. (lazy mode).
<\/setting> - Matches </setting>
Demo

ConfigurationManager class. ConfigurationSection properties cannot be edited when locked

Here is code:
// These is works
Console.WriteLine(Properties.Settings.Default.name);
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
KeyValueConfigurationCollection settings = configFile.AppSettings.Settings;
settings.Add("Port", "12");
// Here it fails
configFile.Save(ConfigurationSaveMode.Modified);
Content of app.config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="ConsoleApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<userSettings>
<ConsoleApplication1.Properties.Settings>
<setting name="name" serializeAs="String">
<value>dasdqweqw</value>
</setting>
</ConsoleApplication1.Properties.Settings>
</userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/></startup></configuration>
Can not understand why it is not working. Code is right or I am doing something wrong? On the line configFile.Save(ConfigurationSaveMode.Modified); it throws an exception "ConfigurationSection properties cannot be edited when locked."
What scenario I have decided to follow:
1. Via Solution explorer I am opening project properties page (Solution explorer > context menu of project node > Properties), then via Settings tab in project properties page I am creating project's application settings (value of Scope parameter is User). This creates Properties class (located in Settings.Designer.cs file) in namespace of the project & corresponding class properties. https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/cftf714c%28v=vs.90%29
2. To create user specific user.config file I have to change added settings & call Properties.Settings.Default.Save() method. If I just call Properties.Settings.Default.Save() without changing settings first this does not create user.config file.
Usage exmple:
Properties.Settings.Default.updateTime = DateTime.UtcNow;
Properties.Settings.Default.Save();
Console.WriteLine((Properties.Settings.Default.updateTime - DateTime.UtcNow).Hours);
Console.ReadLine();
Content of user.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<coonfoo.Properties.Settings>
<setting name="updateTime" serializeAs="String">
<value>06/03/2018 10:42:03</value>
</setting>
</coonfoo.Properties.Settings>
</userSettings>
</configuration>
This should work.
class Program
{
static void Main(string[] args)
{
Configuration roaming = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = roaming.FilePath;
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
KeyValueConfigurationCollection settings = configuration.AppSettings.Settings;
settings.Add("Port", "12");
configuration.Save(ConfigurationSaveMode.Modified);
}
}
Found this which might help you.

How to update setting in app.config.exe file runtime

I am trying to update value of a particular setting in app.config.exe at run time. But as per my code its getting updating in vshost32.exe file which seem to duplicate as app.config.exe. My code is given below
private void btnSubmit_Click(object sender, EventArgs e)
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationSectionGroup applicationSectionGroup = config.GetSectionGroup("applicationSettings");
string d = applicationSectionGroup.Sections[0].ToString(); ;
ConfigurationSection applicationConfigSection = applicationSectionGroup.Sections["Secure_Browser_CS_Version.Properties.Settings"];
ClientSettingsSection clientSection = (ClientSettingsSection)applicationConfigSection;
//Encryption Key Configuration Setting
SettingElement applicationSetting = clientSection.Settings.Get("NavigateURL");
applicationSetting.Value.ValueXml.InnerXml = txtURL.Text;
applicationConfigSection.SectionInformation.ForceSave = true;
config.Save();
}
// app.config.exe
<?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="MyApplicationName.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<MyApplicationName.Properties.Settings>
<setting name="NavigateURL" serializeAs="String">
<value></value>
</setting>
</MyApplicationName.Properties.Settings>
</applicationSettings>
</configuration>
It seems you are doing everything correct, but since you are running using vshost.exe, this is the exe whose configuration is updated.
To run without vshost, uncheck the "Enable the Visual Studio hosting process" checkbox in Project prroperties -> Debug tab:

reading content of an config file into the dll associated with it

I have saved strings in a dll application's setting. I want to retireve them.
Here is the configuration file for my dll:
<?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=xxxxxxxxxxxxxxxxxxxxx" >
<section name="Search.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxx" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<PishiSearch.Properties.Settings>
<setting name="ReadIndex" serializeAs="String">
<value>C:\Index</value>
</setting>
<setting name="WriteIndex" serializeAs="String">
<value>C:\WriteIndex</value>
</setting>
</PishiSearch.Properties.Settings>
</applicationSettings>
</configuration>
It resides in the same directory as my dll. It is called: Search.dll.config
My dll is called: Search.dll
I want to read the values of ReadIndex and WriteIndex from this config file into my dll.
Here is the code:
var executingAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var location = executingAssembly.Location; //C:\MyApp\bin\Debug\Search.dll
var config = ConfigurationManager.OpenExeConfiguration(location);
var sections = config.Sections; //count of this is 21
ConfigurationSectionGroup csg = config.GetSectionGroup("applicationSettings");
ConfigurationSectionCollection csc = csg.Sections;
ConfigurationSection cs = csc.Get("Search.Properties.Settings");
The code works up to getting the last line here. But how do I get the settings strings?
Yes I can use cs.SectionInformation.GetRawXml(); to get the xml and then interrogate it to get the values, but that is a kluge.
How do I read the values? Preferably into a Settings object? Many thanks!
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<applicationSettings>
</applicationSettings>
<appSettings>
<add key="ReadIndex" value="C:\Index"/>
</appSettings>
</configuration>
var executingAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var location = executingAssembly.Location; //C:\MyApp\bin\Debug\Search.dll
var config = ConfigurationManager.OpenExeConfiguration(location);
var sections = config.Sections; //count of this is 21
string s = config.AppSettings.Settings["ReadIndex"].Value.ToString();
you must add tag "appSettings" into tag "configuration" in your file "app.config" in visual studio
like the bellow:
<configuration>
<appSettings>
<add key="ReadIndex" value="aaa"/>
<add key="WriteIndex" value="111"/>
</appSettings>
</configuration>
and then use this bellow code in c#
var appConfig = ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
string userName = appConfig.AppSettings.Settings["ReadIndex"].Value;
string password = appConfig.AppSettings.Settings["WriteIndex"].Value;
if you want to update your configuration you can open the "Search.dll.config" file and then update it.
please refer to the bellow answer:
Reading dll.config (not app.config!) from a plugin module

Categories

Resources