How can I configure my C# project without recompiling? [duplicate] - c#

This question already has answers here:
What is App.config in C#.NET? How to use it?
(7 answers)
Closed 3 years ago.
So I want to execute my program with an .exe, and I would like to configure my program without actually write into the code.
I have some yes-no questions in my code, like:
What would you like to zip? File/Directory.
Edit: I don't want to answer these questions in the console application, I would like to answer these before, like before "settings".
And my question is, can I answer these questions without writing into the code, and make this app executable in this way? Are there any programs for it?
Thanks for the answers!

You have 2 approaches you can use depending on your usage preference, the first suggestion is in case you are using your program and you don't set the values too often
You can use app.config file and add relevant values and call them via your code as variables.
You can write to a xml file or json file a small configuration file abd edit it easily and it is also good for clients using your app to change configuration easily via configuration file.
To do this try use xml serialisation and deserialisation object,
I'll add code sample if required.
Edit
to use external configuration you need the next classes:
1. Configuration data object
[Serializable]
public class Configuration : ICloneable
{
public Configuration()
{
a = "a";
b= "b"
}
public string a { get; set; }
public string b { get; set; }
public object Clone()
{
return new Configuration
{
a = a,
b= b
};
}
}
File write and read class
public class ConfigurationHandler
{
// full path should end with ../file.xml
public string DefaultPath = "yourPath";
public ConfigurationHandler(string path = "")
{
if (!File.Exists(DefaultPath))
{
Directory.CreateDirectory(Path.GetDirectoryName(DefaultPath));
FileStream file = File.Create(DefaultPath);
file.Close();
Configuration = new Configuration();
SaveConfigurations(DefaultPath);
}
}
public void SaveConfigurations(string configPath = "")
{
if (string.IsNullOrEmpty(configPath))
configPath = DefaultPath;
var serializer = new XmlSerializer(typeof(Configuration));
using (TextWriter writer = new StreamWriter(configPath))
{
serializer.Serialize(writer, Configuration);
}
}
public Configuration LoadConfigurations(string configPath = "")
{
if (string.IsNullOrEmpty(configPath))
configPath = DefaultPath;
using (Stream reader = new FileStream(configPath, FileMode.Open))
{
// Call the Deserialize method to restore the object's state.
XmlSerializer serializer = new XmlSerializer(typeof(Configuration));
Configuration = (Configuration)serializer.Deserialize(reader);
}
return Configuration;
}
}
to get the configuration instance you can use it from your program:
static void Main(string[] args)
{
var config = new ConfigurationHandler().LoadConfigurations();
//....
}

Related

C# - Storing struct(s) in setting file

I only wanted to store some main configuration in a settings file, since the configuration may change any time.
The users of my application will be able to manage some stuff in several environments.
Each environment has its own configuration (Paths to network locations basicly).
I built an struct for each environment, but now we have to add some more environments, so it is helpful to store that configuration outside of the source code.
So, let me give you some code. I built two structs to describe each environment:
public struct env_conf
{
string title;
string path_to_xml;
string path_to_sharepoint;
List<subfolder> subfolders;
//Some more strings
public env_conf(string title, string path_to_xml, string path_to_sharepoint ...)
{
//Constructor which is setting the variables
}
}
public struct subfolder
{
string folder;
bool is_standard;
public env_conf(string folder, bool is_standard)
{
//Constructor which is setting the variables
}
}
And this is how the environment configs are set up:
var finance_conf = new env_conf("MyTitle","MyXMLPath","MySPPath",
new List<subfolder>{new subfolder("MySubFolder",true);new subfolder("MySubFolder2",false)}
);
var sales_conf = new env_conf("MySalesTitle","MySalesXMLPath","MySalesSPPath",
new List<subfolder>{new subfolder("MySalesSubFolder",true);new subfolder("MySalesSubFolder2",false)}
);
This last step - the definition of the config-instances shall now be inside of a settings file.
Saving string and also string[] in settings file was no problem for me so far. But now I have more than that...
More than that, I do NOT have Visual Studio. I work with SharpDevelop, which was very good so far.
Marking my structs as serializable was not helpful. Also, when I manually set the type of the setting to MyNamespace.env_conf, it wont appear in the settings designer - only a "?" appears in the Type-field.
So for now, I don't know how to proceed. Also, all the info I find in the internet doesn't seem to help me. Please help me.
How has my XML settings file to be edited?
How has my source code to be edited?
Greetings!
I would do it by creating serializable classes, then you can deserialize the config file to an instance of your class, and you'll have all the settings.
For example, the classes might look like:
[Serializable]
public class EnvironmentConfig
{
public string Title { get; set; }
public string XmlPath { get; set; }
public string SharepointPath { get; set; }
public List<SubFolder> SubFolders { get; set; }
public override string ToString()
{
return $"{Title}: {XmlPath}, {SharepointPath}, {string.Join(", ", SubFolders.Select(s => s.Folder))}";
}
}
[Serializable]
public class SubFolder
{
public string Folder { get; set; }
public bool IsStandard { get; set; }
}
And then in code, you can create an instance of your class, give it some values, and serialize it to a config file. Later, you can deserialize this file to load any changes your users may have made.
This example creates a default config and displays the values to the console. Then it gives the user a chance to modify the file, and displays the new values.
// Create a default config
var defaultEnvCfg = new EnvironmentConfig
{
Title = "USWE Environment",
XmlPath = #"\\server\share\xmlfiles",
SharepointPath = #"\\server\sites\enterpriseportal\documents",
SubFolders = new List<SubFolder>
{
new SubFolder { Folder = "Folder1", IsStandard = true },
new SubFolder { Folder = "Folder2", IsStandard = false }
}
};
// Display original values:
Console.WriteLine(defaultEnvCfg.ToString());
// Serialize the config to a file
var pathToEnvCfg = #"c:\public\temp\Environment.config";
var serializer = new XmlSerializer(defaultEnvCfg.GetType());
using (var writer = new XmlTextWriter(
pathToEnvCfg, Encoding.UTF8) { Formatting = Formatting.Indented })
{
serializer.Serialize(writer, defaultEnvCfg);
}
// Prompt user to change the file
Console.Write($"Please modify the file then press [Enter] when done: {pathToEnvCfg}");
Console.ReadLine();
// Deserialize the modified file and update our object with the new settings
using (var reader = XmlReader.Create(pathToEnvCfg))
{
defaultEnvCfg = (EnvironmentConfig)serializer.Deserialize(reader);
}
// Display new values:
Console.WriteLine(defaultEnvCfg.ToString());
Console.Write("\nDone!\nPress any key to exit...");
Console.ReadKey();

App config in Class library C#

I have a wpf application which is using a dll of a class library. I am unable to access the app.config value in the class library
How I'm trying to access app.config:
ConfigurationSettings.AppSettings["conStr"].ToString();
this is returning a null value
using System.Configuration is also added .
Why don't you just put that value in the Main Project ?
If you're calling the class library from the Main Project. Then the code in the class library uses the AppConfig defined inside the main project.
It is a common practice to have the connection string in the AppConfig for the Main Project and not inside the Class Library.
I recomend to use your own class for save Class Library settings. Something like this:
public class GlobalSettings
{
public double RedFiber { get; set; }
public double GreenFiber { get; set; }
public double BlueFiber { get; set; }
public bool DeleteMinorViews { get; set; }
public static GlobalSettings Load()
{
try
{
return JsonConvert.DeserializeObject<GlobalSettings>(File.ReadAllText(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\YOUR_APP_NAME\\"));
}
catch ()
{
return DefaultSettings;
}
}
public void Save()
{
File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\YOUR_APP_NAME\\", JsonConvert.SerializeObject(this, Formatting.Indented));
}
private static readonly GlobalSettings DefaultSettings = new GlobalSettings()
{
RedFiber = 0,
GreenFiber = 255,
BlueFiber = 0,
DeleteMinorViews = true,
};
}
I had the same issue. Try adding a settings file for your class library to store your values. The value will be stored in the app.config but accessed using the settings file.
This post explains better: Can a class library have an App.config file?
This post goes into more detail about settings files: Best practice to save application settings in a Windows Forms Application
If you prefer not to do the above you can also move your data to the main projects App.config file and it should work.
try
ConfigurationManager.AppSettings["conStr"].ToString();
If the does not work post your App.Config
ConfigurationSettings.AppSettings is obsolete

Serializing CouchbaseClient Error

Is it possible to serialize a CouchbaseClient to write it to a Memory Mapped file?
When I try do this:
[Serializable]
public class DocumentDatabaseConnection
{
public CouchbaseClient DocumentStoreConnection { get; set; }
}
static void main(string [] args)
{
CouchbaseClientConfiguration config = new CouchbaseClientConfiguration();
config.Urls.Add(new Uri("http://localhost:8091" + "/pools/"));
config.Bucket = "myBucket";
config.BucketPassword = "123456";
DocumentDatabaseConnection clientConnection = new DocumentDatabaseConnection();
clientConnection.DocumentStoreConnection = new CouchbaseClient(config);
try
{
//Here is where I try to convert it to a byte array to save in MMF
var myMMFObject = ObjectToByteArray(clientConnection);
WriteObjectToMMF("C:\\TEMP\\TEST.MMF", myMMFObject);
string myMMF = ReadObjectFromMMF("C:\\TEMP\\TEST.MMF").ToString();
}
catch(Exception e)
{
throw;
}
}
I get a SerializationException, for the Couchbase.CouchbaseClient. If it is possible to serialize how would that be done. Couchbase.CouchbaseClient was installed via NuGet.
How would one share a Couchbase.CouchbaseClient accross threads?
The official documentation specifically covers how to instantiate and share a single client instance. I would follow that for best practices, you can find the link here http://docs.couchbase.com/couchbase-sdk-net-1.3/#instantiating-the-client
Also there is some more detail regarding the client for C# located here: http://docs.couchbase.com/couchbase-sdk-net-1.2/#encapsulating-data-access

How can I retrieve list of custom configuration sections in the .config file using C#? [duplicate]

This question already has answers here:
Custom Configuration for app.config - collections of sections?
(2 answers)
Closed 9 years ago.
When I try to retrieve the list of sections in the .config file using
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
the config.Sections collection contains a bunch of system section but none of the sections I have file defined in the configSections tag.
Here is a blog article that should get you what you want. But to ensure that the answer stays available I'm going to drop the code in place here too. In short, make sure you're referencing the System.Configuration assembly and then leverage the ConfigurationManager class to get at the very specific sections you want.
using System;
using System.Configuration;
public class BlogSettings : ConfigurationSection
{
private static BlogSettings settings
= ConfigurationManager.GetSection("BlogSettings") as BlogSettings;
public static BlogSettings Settings
{
get
{
return settings;
}
}
[ConfigurationProperty("frontPagePostCount"
, DefaultValue = 20
, IsRequired = false)]
[IntegerValidator(MinValue = 1
, MaxValue = 100)]
public int FrontPagePostCount
{
get { return (int)this["frontPagePostCount"]; }
set { this["frontPagePostCount"] = value; }
}
[ConfigurationProperty("title"
, IsRequired=true)]
[StringValidator(InvalidCharacters = " ~!##$%^&*()[]{}/;’\"|\\"
, MinLength=1
, MaxLength=256)]
public string Title
{
get { return (string)this["title"]; }
set { this["title"] = value; }
}
}
Make sure you read the blog article - it will give you the background so that you can fit it into your solution.

unable to save settings in app.exe.config

i am facing one problem.
i want to save settings in app.config file
i wrote separate class and defined section in config file..
but when i run the application. it does not save the given values into config file
here is SettingsClass
public class MySetting:ConfigurationSection
{
private static MySetting settings = ConfigurationManager.GetSection("MySetting") as MySetting;
public override bool IsReadOnly()
{
return false;
}
public static MySetting Settings
{
get
{
return settings;
}
}
[ConfigurationProperty("CustomerName")]
public String CustomerName
{
get
{
return settings["CustomerName"].ToString();
}
set
{
settings["CustomerName"] = value;
}
}
[ConfigurationProperty("EmailAddress")]
public String EmailAddress
{
get
{
return settings["EmailAddress"].ToString();
}
set
{
settings["EmailAddress"] = value;
}
}
public static bool Save()
{
try
{
System.Configuration.Configuration configFile = Utility.GetConfigFile();
MySetting mySetting = (MySetting )configFile.Sections["MySetting "];
if (null != mySetting )
{
mySetting .CustomerName = settings["CustomerName"] as string;
mySetting .EmailAddress = settings["EmailAddress"] as string;
configFile.Save(ConfigurationSaveMode.Full);
return true;
}
return false;
}
catch
{
return false;
}
}
}
and this is the code from where i am saving the information in config file
private void SaveCustomerInfoToConfig(String name, String emailAddress)
{
MySetting .Settings.CustomerName = name;
MySetting .Settings.EmailAddress = emailAddress
MySetting .Save();
}
and this is app.config
<configuration>
<configSections>
<section name="MySettings" type="TestApp.MySettings, TestApp"/>
</configSections>
<MySettings CustomerName="" EmailAddress="" />
</configuration>
can u tell me where is the error.. i tried alot and read from internet. but still unable to save information in config file..
i ran the application by double clicking on exe file also.
According to the MSDN: ConfigurationManager.GetSection Method,
The ConfigurationManager.GetSection method accesses run-time configuration information that it cannot change. To change the configuration, you use the Configuration.GetSection method on the configuration file that you obtain by using one of the following Open methods:
OpenExeConfiguration
OpenMachineConfiguration
OpenMappedExeConfiguration
However, if you want to update app.config file, I would read it as an xml document and manipulate it as a normal xml document.
Please see the following example:
Note: this sample is just for proof-of-concept. Should not be used in production as it is.
using System;
using System.Linq;
using System.Xml.Linq;
namespace ChangeAppConfig
{
class Program
{
static void Main(string[] args)
{
MyConfigSetting.CustomerName = "MyCustomer";
MyConfigSetting.EmailAddress = "MyCustomer#Company.com";
MyConfigSetting.TimeStamp = DateTime.Now;
MyConfigSetting.Save();
}
}
//Note: This is a proof-of-concept sample and
//should not be used in production as it is.
// For example, this is not thread-safe.
public class MyConfigSetting
{
private static string _CustomerName;
public static string CustomerName
{
get { return _CustomerName; }
set
{
_CustomerName = value;
}
}
private static string _EmailAddress;
public static string EmailAddress
{
get { return _EmailAddress; }
set
{
_EmailAddress = value;
}
}
private static DateTime _TimeStamp;
public static DateTime TimeStamp
{
get { return _TimeStamp; }
set
{
_TimeStamp = value;
}
}
public static void Save()
{
XElement myAppConfigFile = XElement.Load(Utility.GetConfigFileName());
var mySetting = (from p in myAppConfigFile.Elements("MySettings")
select p).FirstOrDefault();
mySetting.Attribute("CustomerName").Value = CustomerName;
mySetting.Attribute("EmailAddress").Value = EmailAddress;
mySetting.Attribute("TimeStamp").Value = TimeStamp.ToString();
myAppConfigFile.Save(Utility.GetConfigFileName());
}
}
class Utility
{
//Note: This is a proof-of-concept and very naive code.
//Shouldn't be used in production as it is.
//For example, no null reference checking, no file existence checking and etc.
public static string GetConfigFileName()
{
const string STR_Vshostexe = ".vshost.exe";
string appName = Environment.GetCommandLineArgs()[0];
//In case this is running under debugger.
if (appName.EndsWith(STR_Vshostexe))
{
appName = appName.Remove(appName.LastIndexOf(STR_Vshostexe), STR_Vshostexe.Length) + ".exe";
}
return appName + ".config";
}
}
}
I also added "TimeStamp" attribute to MySettings in app.config to check the result easily.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="MySettings" type="TestApp.MySettings, TestApp"/>
</configSections>
<MySettings CustomerName="" EmailAddress="" TimeStamp=""/>
</configuration>
In many cases (in a restricted user scenario) the user do not have write access directly to the application config file. To come around this, you need to use the usersettings.
If you right-click your project and select the tab named "Settings", you can make a list of settings that are stored with the config file. If you select the "Scope" to be "User", the setting are automatically stored in the config file using a type that will automatically store the settings under the users AppData area, where the user allways has write access. The settings are also automatically provided as properties created in the Properties\Settings.Designer.cs code file, and are accessible in your code in Properties.Settings.Default .
Example:
Let's say you add a user setting called CustomerName:
On loading the app, you would want to retreive the value from the stored setting ( either default value as it is in the app config, or if it is stored for this user, the config file for the user):
string value = Properties.Settings.Default.CustomerName;
When you want to change the value, just write to it:
Properties.Settings.Default.CustomerName = "John Doe";
When you want to save all the settings, just call Save:
Properties.Settings.Default.Save();
Note that when you develop, the user file will occationally be reset to the default, but this only happens when building the app. When you just run the app, the settings you store will be read from the user-config file for the app.
If you still want to create your own handling of the settings, you can try this once, and look at what VisualStudio has automatically created for you to get an idea of what you need to get this working.
In order to actually update the config file, you'll need to call .Save() on the Configuration object - not just your config section object.
You should check out Jon Rista's three-part series on .NET 2.0 configuration up on CodeProject.
Unraveling the mysteries of .NET 2.0 configuration
Decoding the mysteries of .NET 2.0 configuration
Cracking the mysteries of .NET 2.0 configuration
Highly recommended, well written and extremely helpful! It shows all the ins and outs of dealing with .NET 2.0 and up configuration, and helped me very much getting a grasp on the subject.
Marc
Be aware that the appname.vshost.exe.Config is reverted to it's the original state at the end of the debugging session. So you might be saving to the file (you can check by using Notepad during execution), then losing the saved contents when the debugging stops.

Categories