I am trying to use the System.Collections.Specialized.StringDictionary to save paired values in to settings.settings file.
I run my application, updated the Settings, did Settings.Default.Save()
and when started the app again noticed the new settings did not work!
Looking in the created user.config, the StringDictionary was serialized
to <value />.
Please suggest me if there is any alternative or work around to make this work.
#kns provided the solution for me. I just added the line [global::System.Configuration.SettingsSerializeAs(global::System.Configuration.SettingsSerializeAs.Binary)] above the StringDictionary property in the Settings.Designer.cs file as follows:
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.SettingsSerializeAs(global::System.Configuration.SettingsSerializeAs.Binary)]
public global::System.Collections.Specialized.StringDictionary customSetPhrases {
get {
return ((global::System.Collections.Specialized.StringDictionary)(this["customSetPhrases"]));
}
set {
this["customSetPhrases"] = value;
}
}
where customSetPhrases is the name of my setting. This seems to have done the trick.
Related
Let's say I have a command line application that needs to reference some form of a user configuration file. Furthermore, the values contained within this file are to only be updated by the user manually -- there won't be any ways of updating the configuration file within the application, nor will the application seek out any inputs once started. If a configuration listing is missing from the configuration file, a default value should be used instead.
I understand that Visual Studio / .NET Framework offer tools for creating such constructs (i.e. Settings and App.configs), but I'm not sure I'm using them correctly -- or if I should be using them at all.
I created a Settings file and threw in a couple of default settings (e.g. SomeBooleanFlag is a bool with a default value of 'False'). This addition of course was reflected within my App.config. However, here is where the dilemma lies: how should I read from the App.config?
Currently, I've created a class to abstract away the configuration manager / settings stuff:
class AppSettings
{
public static bool SomeBooleanFlag
{
get
{
try
{
string rawValue = ConfigurationManager.AppSettings["SomeBooleanFlag"];
bool userSetSomeBooleanFlag;
bool userValueParsed = bool.TryParse(rawValue, out userSetSomeBooleanFlag);
return (userValueParsed) ? userSetSomeBooleanFlag : Settings.Default.SomeBooleanFlag;
}
catch
{
return Settings.Default.SomeBooleanFlag;
}
}
}
}
Which then gives me the ability to write:
if (AppSettings.SomeBooleanFlag)
{
/* Do Something... */
}
However, this does not seem like a clean way to approach the problem I stated above. Any help would be greatly appreciated!
Instead of coding your own Application Settings wrapper, you can reuse the functionality built into Visual Studio to generate this wrapper for you. See How to: Add or Remove Application Settings and How To: Read Settings at Run Time With C#. In addition to specifying the type of the setting you can also indicate the scope (User or Application).
Following the steps in the aforementioned articles, it will add the settings to your App.config file, below is an example:
<configuration>
...
<applicationSettings>
<ConsoleApplication1.Properties.Settings>
<setting name="TestKey" serializeAs="String">
<value>TestValue</value>
</setting>
</ConsoleApplication1.Properties.Settings>
</applicationSettings>
...
</configuration>
And you can access these settings as follows:
string s = Properties.Settings.Default.TestKey;
I have a windows application that writes user settings using the method described here:
http://msdn.microsoft.com/en-us/library/bb397755(v=vs.110).aspx
These settings are saved to a file in the users directory e.g:
c:\users\{you name}\Local\{Company}\{product}\user.config
I need to access these settings in a companion console application. Is this possible, at the moment the settings return null when I try to access them from the console application.
The code itself will look something like this:
To save the settings in App1:
namespace Application1{
public class DemoSave{
public void DoWork(){
Application1.Properties.Settings.Default.CustomSettings.Title ="someValue";
Application1.Properties.Settings.Default.Save();
}
}
}
To read the settings in another app:
namespace Application2{
public class Demo{
public void DoWork(){
var title = Application1.Properties.Settings.Default.CustomSettings.Title;
}
}
}
In Application2 the Application1.Properties.Settings.Default.CustomSettings property is null.
Last time I did something similar, I had two projects in a solution (a windows service and a wpf application), and I had to reference the WPF app in the Win Service project to access it's settings (I assume you're talking about Namespace.Properties.Settings). It seems to have worked fine for me. In this case i had to set the access modifier on the settings to public though. I'm not sure if this is the best way, but it worked for me for something very small and insignificant.
Are you even sure your pointing at the right place when you modifies/read the settings files.
Because that might be why it doesn't work.
This is very frustrating... I can set the Configuration File for a Windows Forms Application just fine. Consider this:
public static void Main(){
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", #"SharedAppConfig.config");
//do other things
}
However, in a WPF application, this doesn't seem to work! If I set this value, the value of the AppDomain.CurrentDomain.SetupInformation.ConfigurationFile property is correct, but any calls to that configuration file while debugging yield no results. There are WCF configuration settings in an App.config that I need to share between application, so this is my proposed solution. Is it possible to dynamically set the location of my config file in WPF?
Help! Thanks!
You should be able to do something along the lines of:
using System.Configuration;
public class TryThis
{
Configuration config = ConfigurationManager.OpenExeConfiguration("C:\PathTo\app.exe");
public static void Main()
{
// Get something from the config to test.
string test = config.AppSettings.Settings["TestSetting"].Value;
// Set a value in the config file.
config.AppSettings.Settings["TestSetting"].Value = test;
// Save the changes to disk.
config.Save(ConfigurationSaveMode.Modified);
}
}
NOTE: This will attempt to open a file named app.exe.config at C:\PathTo. This also REQUIRES that a file exists at the same path with the name "app.exe". The "app.exe" file can just be an empty file though. For your case I'd almost make a shared "Config.dll" library that would handle the config file.
~md5sum~
Is this on the service side or the client side? If on the service side, it is often the case that the service is running in its own AppDomain, so that if you set AppDomain.CurrentDomain.SetData(...) it won't apply to the service configuration.
I'm not entirely sure how to get around this, but you should be able to control the service's configuration by implementing your own ServiceHost.
Hi All,
I have two .net applications, these applications want to talk to each other, I made a setting in the first project as follows
[CompilerGeneratedAttribute()]
[GeneratedCodeAttribute("SettingsSingleFileGenerator", "9.0.0.0")]
public sealed partial class Settings :ApplicationSettingsBase
{
[UserScopedSettingAttribute()]
[DebuggerNonUserCodeAttribute()]
[DefaultSettingValueAttribute("False")]
public bool BeginWorking {
get {
return ((bool)(this["BeginWorking"]));
}
set {
this["BeginWorking"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool Result {
get {
return ((bool)(this["Result"]));
}
set {
this["Result"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool Completed{
get {
return ((bool)(this["Completed"]));
}
set {
this["Completed"] = value;
}
}
}
the second project may set the BeginWorking setting for the first project in order to tell it to work, and waits for the Completed setting to be set and get the result from the Result setting.
Is that possible and how??
I feel it may be not easy to answer but excuse me I'm get unable to think more.
Thanks All
User level app settings are isolated in a subdirectory of AppData. One app cannot find the settings of another app. Just use a plain file.
I've not used it but .NET Remoting might be more suitable to your needs see MSDN link text
Settings are persisted to a configuration file that is saved on disk. As far as I know the default place for this is in the user's application directory (%appdata%). Since this file is persisted to disk your other application would need to be able to read and write to this same file.
If both applications are reading and writing to the same file then you should be able to do what you want to do.
I have a Visual Studio setup project that has an Installer class. In the installer class I set a setting as follows:
MessageBox.Show(Properties.Settings.Default.MySetting);
Properties.Settings.Default.MySetting = "Foo";
Properties.Settings.Default.Save();
MessageBox.Show(Properties.Settings.Default.MySetting);
The problem is that even though I know that this code is being executed (I am doing other stuff), the setting is never set!!
The message boxes do suggest that the value is being set, but when I go to the .config file the value is still blank!
Anyone have any ideas why and/or a possible workaround?
What I do for my installers is to use the "file" attribute in App.Config. The appSettings block takes a "file" attribute, like so:
<appSettings file="user.config">
<add key="foo" value="some value unchanged by setup"/>
</appSettings>
The "file" attribute is sort of like CSS, in that the most specific setting wins. If you have "foo" defined in user.config as well as App.config, the value in user.config is used.
Then, I have a config generator that writes out a second appSettings block to user.config (or whatever you want to call it), using values in a dictionary.
using System.Collections.Generic;
using System.Text;
using System.Xml;
namespace Utils
{
public class ConfigGenerator
{
public static void WriteExternalAppConfig(string configFilePath, IDictionary<string, string> userConfiguration)
{
using (XmlTextWriter xw = new XmlTextWriter(configFilePath, Encoding.UTF8))
{
xw.Formatting = Formatting.Indented;
xw.Indentation = 4;
xw.WriteStartDocument();
xw.WriteStartElement("appSettings");
foreach (KeyValuePair<string, string> pair in userConfiguration)
{
xw.WriteStartElement("add");
xw.WriteAttributeString("key", pair.Key);
xw.WriteAttributeString("value", pair.Value);
xw.WriteEndElement();
}
xw.WriteEndElement();
xw.WriteEndDocument();
}
}
}
}
In your installer, just add something like the following in your Install method:
string configFilePath = string.Format("{0}{1}User.config", targetDir, Path.DirectorySeparatorChar);
IDictionary<string, string> userConfiguration = new Dictionary<string, string>();
userConfiguration["Server"] = Context.Parameters["Server"];
userConfiguration["Port"] = Context.Parameters["Port"];
ConfigGenerator.WriteExternalAppConfig(configFilePath, userConfiguration);
We use it for our test, training, and production servers, so all we have to do is specify the machine name and password during the install, and everything's taken care of for us. It used to be a 3-hour process, including going through multiple config files to set passwords. Now it's almost entirely automated.
Hope this helps.
Well in the end I gave up and had a RunOnce type of method to do this stuff after the app was installed.
I honestly don't know if this is supported during an installer - but if it is, make sure you're calling Save() on Settings.Default.
The short answer is that it's not supported in installer classes. You just need to understand that installer class methods are called from msiexec.exe running from the system directory, and that environment can't possibly know that you have a settings file somewhere in a directory that it is completely unaware of. That's why it works with code that explicitly goes to the installed location of the file and updates it there.