app.settings

  • Thread starter Thread starter Thomas Kehl
  • Start date Start date
T

Thomas Kehl

Hello.

I would extend the app.config with the fallowing configSection:

<plugins>
<Test1 active="1" />
<Test2 active="0" />
</plugins>

Now, I don't now, how does I have declare the section and after read the
values with the ConfigManager.
Can anybody help me?

Thanks.

Best Regards, Thomas
 
The section should be placed inside of the <appSettings> section, but you
couldn't just add the data in the form that you listed. It needs to added as
simple key/value pair data and would look like this:

<configuration>
<appSettings>
<add key="Test1" value="active" />
<add key="Test2" value="inactive" />
</appSettings>
</configuration>

and retrieved like this:

String s1 =
System.Configuration.ConfigurationSettings.AppSettings.Get("Test1").ToString();
String s2 =
System.Configuration.ConfigurationSettings.AppSettings.Get("Test2").ToString();

-Scott
 
First, you need a <configSections> to identify your sections and the types
and assemblies that know how to read your sections, something like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="features"
type="MySample.FeatureSection, MyAssembly" />
</configSections>

You could have multiple <section> definitions.

That is followed by instances of the sections, like this:

<features>
<feature
name="Client"
title="My Sample Client"
description="An example"
status="Installing Client tools"
productcode="{345BC2AA-A7C1-44c8-9653-AC355E744D8E}"
command="msiexec"
arguments="-i SetupClient.msi &quot;TARGETDIR={0}&quot;" />
<feature
name="Server"
title="My Sample Server"
description="This is a sample"
status="Installing Server"
productcode="{BCD2C3AA-78CB-4662-ABCF-33D53CAADF58}"
command="msiexec"
arguments="-i SetupScheduler.msi &quot;TARGETDIR={0}&quot;
DEFQUAL=&quot;/INSTANCE={1}&quot;"
requiresmsmq="true"
requiressql="true"/>
</features>
</configuration>

In your "MyAssembly" assembly, you have to define the section, like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
/// <summary>
/// The FeatureSection class is the starting point for the features
section of
/// our application configuration file. This is a very simple class
because it just
/// needs to identify and return the default collection which is a
FeatureCollection.
/// </summary>
public sealed class FeatureSection : ConfigurationSection
{
public FeatureSection()
{
}

[ConfigurationProperty("", IsDefaultCollection = true)]
public FeatureCollection Features
{
get
{
return (FeatureCollection)base[""];
}
}
}
}



Then, you have to define the FeatureCollection (or PluginCOllection etc.),
like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
public sealed class FeatureCollection : ConfigurationElementCollection
{
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMap;
}
}

protected override ConfigurationElement CreateNewElement()
{
return new FeatureElement();
}

protected override ConfigurationElement CreateNewElement(string
elementName)
{
return new FeatureElement(elementName);
}

protected override object GetElementKey(ConfigurationElement
element)
{
return ((FeatureElement)element).Name;
}

protected override string ElementName
{
get
{
return "feature";
}
}
}
}


And finally, define the Feature element, like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
/// <summary>
/// The FeatureElement class defines the syntax and options that can be
specified in the
/// &lt;Feature&gt; element in the application configuration file.
/// Each &lt;Feature&gt; element defines one feature that the user can
select to install.
/// </summary>
public sealed class FeatureElement : ConfigurationElement
{
public FeatureElement()
{
}

public FeatureElement(string newName)
{
Name = newName;
}

public FeatureElement(string newName, string newDescription, string
newCommand)
{
Name = newName;
Description = newDescription;
Command = newCommand;
}

/// <summary>
/// The name attribute is required and must be unique within the
collection.
/// </summary>
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}

/// <summary>
/// The title attribute specifies the text that is in the feature
selection list box.
/// </summary>
[ConfigurationProperty("title", IsRequired=true)]
public string Title
{
get
{
return (string)this["title"];
}
set
{
this["title"] = value;
}
}

/// <summary>
/// The status attribute specifies the text that is displayed when
the feature
/// is being executed. If the text isn't defined, the title is
used.
/// </summary>
[ConfigurationProperty("status", IsRequired = false)]
public string Status
{
get
{
string returnString = (string)this["status"];
if (returnString.Length == 0)
{
returnString = (string)this["description"];
}
return returnString;
}
set
{
this["status"] = value;
}
}

/// <summary>
/// The description attribute specfies the text that is displayed
under the feature
/// selection list box when the feature is the selected (checked or
not).
/// </summary>
[ConfigurationProperty("description", IsRequired = false)]
public string Description
{
get
{
return (string)this["description"];
}
set
{
this["description"] = value;
}
}

/// <summary>
/// The command attribute specifies the command that is executed to
install the feature.
/// You specify either the command or the download URL.
/// </summary>
[ConfigurationProperty("command", IsRequired = false)]
public string Command
{
get
{
return (string)this["command"];
}
set
{
this["command"] = value;
}
}

/// <summary>
/// The arguments attribute specifies the arguments passed to the
command.
/// You can use "{0}" where you want the target directory
substituted.
/// </summary>
[ConfigurationProperty("arguments", IsRequired = false)]
public string Arguments
{
get
{
return (string)this["arguments"];
}
set
{
this["arguments"] = value;
}
}

/// <summary>
/// The sourcefile attribute is used when the command is "copy"
/// </summary>
[ConfigurationProperty("sourcefile", IsRequired = false)]
public string SourceFile
{
get
{
return (string)this["sourcefile"];
}
set
{
this["sourcefile"] = value;
}
}

/// <summary>
/// The destinationfile attribute is used when the command is "copy"
/// and when downloading a file.
/// </summary>
[ConfigurationProperty("destinationfile", IsRequired = false)]
public string DestinationFile
{
get
{
return (string)this["destinationfile"];
}
set
{
this["destinationfile"] = value;
}
}

/// <summary>
/// The overwrite attribute is used when the command is "copy"
/// </summary>
[ConfigurationProperty("overwrite", DefaultValue = false, IsRequired
= false)]
public bool Overwrite
{
get
{
return (bool)this["overwrite"];
}
set
{
this["overwrite"] = value;
}
}

/// <summary>
/// The productcode is used when the command is msiexec. The
product code is the GUID
/// that identifies this product and we need it to determine if the
product is already installed.
/// If the product is already installed, we add REINSTALL=ALL and
REINSTALLMODE=vomus to the
/// msiexec command.
/// </summary>
[ConfigurationProperty("productcode", IsRequired = false)]
public string ProductCode
{
get
{
return (string)this["productcode"];
}
set
{
this["productcode"] = value;
}
}

/// <summary>
/// The services attribute is used to specify a code that identifies
the services
/// that this feature installs.
/// </summary>
[ConfigurationProperty("services", IsRequired = false)]
public string Services
{
get
{
return (string)this["services"];
}
set
{
this["services"] = value;
}
}

/// <summary>
/// If this is set to true, we will make check for SQL Server.
/// </summary>
[ConfigurationProperty("requiressql", DefaultValue = false,
IsRequired = false)]
public bool RequiresSql
{
get
{
return (bool)this["requiressql"];
}
set
{
this["requiressql"] = value;
}
}

/// <summary>
/// If this is set to true, we will check for MSMQ.
/// </summary>
[ConfigurationProperty("requiresmsmq", DefaultValue = false,
IsRequired = false)]
public bool RequiresMsmq
{
get
{
return (bool)this["requiresmsmq"];
}
set
{
this["requiresmsmq"] = value;
}
}

/// <summary>
/// The checked attribute defines the default checked state of this
feature.
/// If any of the features is already installed, the checked
features are the
/// ones that are already installed. If none of the features are
installed,
/// we get the checked state from this attribute.
/// </summary>
[ConfigurationProperty("checked", DefaultValue = true, IsRequired =
false)]
public bool Checked
{
get
{
return (bool)this["checked"];
}
set
{
this["checked"] = value;
}
}

/// <summary>
/// Specifies a delay after the command completes.
/// </summary>
[ConfigurationProperty("delay", DefaultValue = 0, IsRequired =
false)]
public int Delay
{
get
{
return (int)this["delay"];
}
set
{
this["delay"] = value;
}
}

public bool IsInstalled
{
get
{
return m_IsInstalled;
}
set
{
m_IsInstalled = value;
}
}
private bool m_IsInstalled;

public override string ToString()
{
return Title;
}
}
}



Now that it is all defined, you can use it like this:

FeatureSection featureSection =
ConfigurationManager.GetSection("features") as FeatureSection;



Thanks for listening!

John Vottero
http://www.JAMSScheduler.com
 
Hi John

Thank you. I have no try this. When I use it, I became a
System.Configuration.ConfigurationErrorsException. The Message is
(translated from german to english):
The property of the configuration can not be derived from
ConfigurationSection.

Here is my app.config the the code:

<configSections>
<section name="plugins"
type="mt.communicationServices.library.PluginSection,
mt.CommunicationServices.Library" />
<plugins>
<plugin name="Test1" active="1"></plugin>
<plugin name="Test2" active="0"></plugin>
</plugins>


using System.Configuration;

namespace mt.communicationServices.library {
public sealed class PluginSection : ConfigurationSection {
[ConfigurationProperty("", IsDefaultCollection = true)]
public PluginSection Plugins {
get { return (PluginSection) base[""]; }
}
}


public sealed class PluginCollection : ConfigurationElementCollection {
public override ConfigurationElementCollectionType CollectionType {
get { return ConfigurationElementCollectionType.BasicMap; }
}

protected override ConfigurationElement CreateNewElement() {
return new PluginElement();
}

protected override ConfigurationElement CreateNewElement(string
elementName) {
return new PluginElement(elementName);
}

protected override object GetElementKey(ConfigurationElement
element) {
return ((PluginElement) element).Name;
}

protected override string ElementName {
get { return "plugin"; }
}
}


public sealed class PluginElement : ConfigurationElement {
public PluginElement() {
}

public PluginElement(string newName) {
Name = newName;
}

public PluginElement(string newName, string newActive) {
Name = newName;
Active = newActive;
}

[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name {
get { return (string) this["name"]; }
set { this["name"] = value; }
}

[ConfigurationProperty("active", IsRequired = true)]
public string Active {
get { return (string) this["active"]; }
set { this["active"] = value; }
}

public override string ToString() {
return Name;
}
}
}


can you help me one more time?

Thank you.

Thomas


John said:
First, you need a <configSections> to identify your sections and the
types and assemblies that know how to read your sections, something like
this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="features"
type="MySample.FeatureSection, MyAssembly" />
</configSections>

You could have multiple <section> definitions.

That is followed by instances of the sections, like this:

<features>
<feature
name="Client"
title="My Sample Client"
description="An example"
status="Installing Client tools"
productcode="{345BC2AA-A7C1-44c8-9653-AC355E744D8E}"
command="msiexec"
arguments="-i SetupClient.msi &quot;TARGETDIR={0}&quot;" />
<feature
name="Server"
title="My Sample Server"
description="This is a sample"
status="Installing Server"
productcode="{BCD2C3AA-78CB-4662-ABCF-33D53CAADF58}"
command="msiexec"
arguments="-i SetupScheduler.msi &quot;TARGETDIR={0}&quot;
DEFQUAL=&quot;/INSTANCE={1}&quot;"
requiresmsmq="true"
requiressql="true"/>
</features>
</configuration>

In your "MyAssembly" assembly, you have to define the section, like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
/// <summary>
/// The FeatureSection class is the starting point for the features
section of
/// our application configuration file. This is a very simple class
because it just
/// needs to identify and return the default collection which is a
FeatureCollection.
/// </summary>
public sealed class FeatureSection : ConfigurationSection
{
public FeatureSection()
{
}

[ConfigurationProperty("", IsDefaultCollection = true)]
public FeatureCollection Features
{
get
{
return (FeatureCollection)base[""];
}
}
}
}



Then, you have to define the FeatureCollection (or PluginCOllection
etc.), like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
public sealed class FeatureCollection : ConfigurationElementCollection
{
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMap;
}
}

protected override ConfigurationElement CreateNewElement()
{
return new FeatureElement();
}

protected override ConfigurationElement CreateNewElement(string
elementName)
{
return new FeatureElement(elementName);
}

protected override object GetElementKey(ConfigurationElement
element)
{
return ((FeatureElement)element).Name;
}

protected override string ElementName
{
get
{
return "feature";
}
}
}
}


And finally, define the Feature element, like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
/// <summary>
/// The FeatureElement class defines the syntax and options that can
be specified in the
/// &lt;Feature&gt; element in the application configuration file.
/// Each &lt;Feature&gt; element defines one feature that the user
can select to install.
/// </summary>
public sealed class FeatureElement : ConfigurationElement
{
public FeatureElement()
{
}

public FeatureElement(string newName)
{
Name = newName;
}

public FeatureElement(string newName, string newDescription,
string newCommand)
{
Name = newName;
Description = newDescription;
Command = newCommand;
}

/// <summary>
/// The name attribute is required and must be unique within the
collection.
/// </summary>
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}

/// <summary>
/// The title attribute specifies the text that is in the feature
selection list box.
/// </summary>
[ConfigurationProperty("title", IsRequired=true)]
public string Title
{
get
{
return (string)this["title"];
}
set
{
this["title"] = value;
}
}

/// <summary>
/// The status attribute specifies the text that is displayed
when the feature
/// is being executed. If the text isn't defined, the title is
used.
/// </summary>
[ConfigurationProperty("status", IsRequired = false)]
public string Status
{
get
{
string returnString = (string)this["status"];
if (returnString.Length == 0)
{
returnString = (string)this["description"];
}
return returnString;
}
set
{
this["status"] = value;
}
}

/// <summary>
/// The description attribute specfies the text that is displayed
under the feature
/// selection list box when the feature is the selected (checked
or not).
/// </summary>
[ConfigurationProperty("description", IsRequired = false)]
public string Description
{
get
{
return (string)this["description"];
}
set
{
this["description"] = value;
}
}

/// <summary>
/// The command attribute specifies the command that is executed
to install the feature.
/// You specify either the command or the download URL.
/// </summary>
[ConfigurationProperty("command", IsRequired = false)]
public string Command
{
get
{
return (string)this["command"];
}
set
{
this["command"] = value;
}
}

/// <summary>
/// The arguments attribute specifies the arguments passed to the
command.
/// You can use "{0}" where you want the target directory
substituted.
/// </summary>
[ConfigurationProperty("arguments", IsRequired = false)]
public string Arguments
{
get
{
return (string)this["arguments"];
}
set
{
this["arguments"] = value;
}
}

/// <summary>
/// The sourcefile attribute is used when the command is "copy"
/// </summary>
[ConfigurationProperty("sourcefile", IsRequired = false)]
public string SourceFile
{
get
{
return (string)this["sourcefile"];
}
set
{
this["sourcefile"] = value;
}
}

/// <summary>
/// The destinationfile attribute is used when the command is "copy"
/// and when downloading a file.
/// </summary>
[ConfigurationProperty("destinationfile", IsRequired = false)]
public string DestinationFile
{
get
{
return (string)this["destinationfile"];
}
set
{
this["destinationfile"] = value;
}
}

/// <summary>
/// The overwrite attribute is used when the command is "copy"
/// </summary>
[ConfigurationProperty("overwrite", DefaultValue = false,
IsRequired = false)]
public bool Overwrite
{
get
{
return (bool)this["overwrite"];
}
set
{
this["overwrite"] = value;
}
}

/// <summary>
/// The productcode is used when the command is msiexec. The
product code is the GUID
/// that identifies this product and we need it to determine if
the product is already installed.
/// If the product is already installed, we add REINSTALL=ALL and
REINSTALLMODE=vomus to the
/// msiexec command.
/// </summary>
[ConfigurationProperty("productcode", IsRequired = false)]
public string ProductCode
{
get
{
return (string)this["productcode"];
}
set
{
this["productcode"] = value;
}
}

/// <summary>
/// The services attribute is used to specify a code that
identifies the services
/// that this feature installs.
/// </summary>
[ConfigurationProperty("services", IsRequired = false)]
public string Services
{
get
{
return (string)this["services"];
}
set
{
this["services"] = value;
}
}

/// <summary>
/// If this is set to true, we will make check for SQL Server.
/// </summary>
[ConfigurationProperty("requiressql", DefaultValue = false,
IsRequired = false)]
public bool RequiresSql
{
get
{
return (bool)this["requiressql"];
}
set
{
this["requiressql"] = value;
}
}

/// <summary>
/// If this is set to true, we will check for MSMQ.
/// </summary>
[ConfigurationProperty("requiresmsmq", DefaultValue = false,
IsRequired = false)]
public bool RequiresMsmq
{
get
{
return (bool)this["requiresmsmq"];
}
set
{
this["requiresmsmq"] = value;
}
}

/// <summary>
/// The checked attribute defines the default checked state of
this feature.
/// If any of the features is already installed, the checked
features are the
/// ones that are already installed. If none of the features are
installed,
/// we get the checked state from this attribute.
/// </summary>
[ConfigurationProperty("checked", DefaultValue = true, IsRequired
= false)]
public bool Checked
{
get
{
return (bool)this["checked"];
}
set
{
this["checked"] = value;
}
}

/// <summary>
/// Specifies a delay after the command completes.
/// </summary>
[ConfigurationProperty("delay", DefaultValue = 0, IsRequired =
false)]
public int Delay
{
get
{
return (int)this["delay"];
}
set
{
this["delay"] = value;
}
}

public bool IsInstalled
{
get
{
return m_IsInstalled;
}
set
{
m_IsInstalled = value;
}
}
private bool m_IsInstalled;

public override string ToString()
{
return Title;
}
}
}



Now that it is all defined, you can use it like this:

FeatureSection featureSection =
ConfigurationManager.GetSection("features") as FeatureSection;



Thanks for listening!

John Vottero
http://www.JAMSScheduler.com


Thomas Kehl said:
Hello.

I would extend the app.config with the fallowing configSection:

<plugins>
<Test1 active="1" />
<Test2 active="0" />
</plugins>

Now, I don't now, how does I have declare the section and after read
the values with the ConfigManager.
Can anybody help me?

Thanks.

Best Regards, Thomas
 
In your PluginSection class, the Plugins property should return a
PluginCollection, not a PluginSection.


Thomas Kehl said:
Hi John

Thank you. I have no try this. When I use it, I became a
System.Configuration.ConfigurationErrorsException. The Message is
(translated from german to english):
The property of the configuration can not be derived from
ConfigurationSection.

Here is my app.config the the code:

<configSections>
<section name="plugins"
type="mt.communicationServices.library.PluginSection,
mt.CommunicationServices.Library" />
<plugins>
<plugin name="Test1" active="1"></plugin>
<plugin name="Test2" active="0"></plugin>
</plugins>


using System.Configuration;

namespace mt.communicationServices.library {
public sealed class PluginSection : ConfigurationSection {
[ConfigurationProperty("", IsDefaultCollection = true)]
public PluginSection Plugins {
get { return (PluginSection) base[""]; }
}
}


public sealed class PluginCollection : ConfigurationElementCollection
{
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}

protected override ConfigurationElement CreateNewElement() {
return new PluginElement();
}

protected override ConfigurationElement CreateNewElement(string
elementName) {
return new PluginElement(elementName);
}

protected override object GetElementKey(ConfigurationElement
element) {
return ((PluginElement) element).Name;
}

protected override string ElementName {
get { return "plugin"; }
}
}


public sealed class PluginElement : ConfigurationElement {
public PluginElement() {
}

public PluginElement(string newName) {
Name = newName;
}

public PluginElement(string newName, string newActive) {
Name = newName;
Active = newActive;
}

[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name {
get { return (string) this["name"]; }
set { this["name"] = value; }
}

[ConfigurationProperty("active", IsRequired = true)]
public string Active {
get { return (string) this["active"]; }
set { this["active"] = value; }
}

public override string ToString() {
return Name;
}
}
}


can you help me one more time?

Thank you.

Thomas


John said:
First, you need a <configSections> to identify your sections and the
types and assemblies that know how to read your sections, something like
this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="features"
type="MySample.FeatureSection, MyAssembly" />
</configSections>

You could have multiple <section> definitions.

That is followed by instances of the sections, like this:

<features>
<feature
name="Client"
title="My Sample Client"
description="An example"
status="Installing Client tools"
productcode="{345BC2AA-A7C1-44c8-9653-AC355E744D8E}"
command="msiexec"
arguments="-i SetupClient.msi &quot;TARGETDIR={0}&quot;" />
<feature
name="Server"
title="My Sample Server"
description="This is a sample"
status="Installing Server"
productcode="{BCD2C3AA-78CB-4662-ABCF-33D53CAADF58}"
command="msiexec"
arguments="-i SetupScheduler.msi &quot;TARGETDIR={0}&quot;
DEFQUAL=&quot;/INSTANCE={1}&quot;"
requiresmsmq="true"
requiressql="true"/>
</features>
</configuration>

In your "MyAssembly" assembly, you have to define the section, like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
/// <summary>
/// The FeatureSection class is the starting point for the features
section of
/// our application configuration file. This is a very simple class
because it just
/// needs to identify and return the default collection which is a
FeatureCollection.
/// </summary>
public sealed class FeatureSection : ConfigurationSection
{
public FeatureSection()
{
}

[ConfigurationProperty("", IsDefaultCollection = true)]
public FeatureCollection Features
{
get
{
return (FeatureCollection)base[""];
}
}
}
}



Then, you have to define the FeatureCollection (or PluginCOllection
etc.), like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
public sealed class FeatureCollection : ConfigurationElementCollection
{
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMap;
}
}

protected override ConfigurationElement CreateNewElement()
{
return new FeatureElement();
}

protected override ConfigurationElement CreateNewElement(string
elementName)
{
return new FeatureElement(elementName);
}

protected override object GetElementKey(ConfigurationElement
element)
{
return ((FeatureElement)element).Name;
}

protected override string ElementName
{
get
{
return "feature";
}
}
}
}


And finally, define the Feature element, like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
/// <summary>
/// The FeatureElement class defines the syntax and options that can
be specified in the
/// &lt;Feature&gt; element in the application configuration file.
/// Each &lt;Feature&gt; element defines one feature that the user can
select to install.
/// </summary>
public sealed class FeatureElement : ConfigurationElement
{
public FeatureElement()
{
}

public FeatureElement(string newName)
{
Name = newName;
}

public FeatureElement(string newName, string newDescription,
string newCommand)
{
Name = newName;
Description = newDescription;
Command = newCommand;
}

/// <summary>
/// The name attribute is required and must be unique within the
collection.
/// </summary>
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}

/// <summary>
/// The title attribute specifies the text that is in the feature
selection list box.
/// </summary>
[ConfigurationProperty("title", IsRequired=true)]
public string Title
{
get
{
return (string)this["title"];
}
set
{
this["title"] = value;
}
}

/// <summary>
/// The status attribute specifies the text that is displayed when
the feature
/// is being executed. If the text isn't defined, the title is
used.
/// </summary>
[ConfigurationProperty("status", IsRequired = false)]
public string Status
{
get
{
string returnString = (string)this["status"];
if (returnString.Length == 0)
{
returnString = (string)this["description"];
}
return returnString;
}
set
{
this["status"] = value;
}
}

/// <summary>
/// The description attribute specfies the text that is displayed
under the feature
/// selection list box when the feature is the selected (checked
or not).
/// </summary>
[ConfigurationProperty("description", IsRequired = false)]
public string Description
{
get
{
return (string)this["description"];
}
set
{
this["description"] = value;
}
}

/// <summary>
/// The command attribute specifies the command that is executed
to install the feature.
/// You specify either the command or the download URL.
/// </summary>
[ConfigurationProperty("command", IsRequired = false)]
public string Command
{
get
{
return (string)this["command"];
}
set
{
this["command"] = value;
}
}

/// <summary>
/// The arguments attribute specifies the arguments passed to the
command.
/// You can use "{0}" where you want the target directory
substituted.
/// </summary>
[ConfigurationProperty("arguments", IsRequired = false)]
public string Arguments
{
get
{
return (string)this["arguments"];
}
set
{
this["arguments"] = value;
}
}

/// <summary>
/// The sourcefile attribute is used when the command is "copy"
/// </summary>
[ConfigurationProperty("sourcefile", IsRequired = false)]
public string SourceFile
{
get
{
return (string)this["sourcefile"];
}
set
{
this["sourcefile"] = value;
}
}

/// <summary>
/// The destinationfile attribute is used when the command is
"copy"
/// and when downloading a file.
/// </summary>
[ConfigurationProperty("destinationfile", IsRequired = false)]
public string DestinationFile
{
get
{
return (string)this["destinationfile"];
}
set
{
this["destinationfile"] = value;
}
}

/// <summary>
/// The overwrite attribute is used when the command is "copy"
/// </summary>
[ConfigurationProperty("overwrite", DefaultValue = false,
IsRequired = false)]
public bool Overwrite
{
get
{
return (bool)this["overwrite"];
}
set
{
this["overwrite"] = value;
}
}

/// <summary>
/// The productcode is used when the command is msiexec. The
product code is the GUID
/// that identifies this product and we need it to determine if
the product is already installed.
/// If the product is already installed, we add REINSTALL=ALL and
REINSTALLMODE=vomus to the
/// msiexec command.
/// </summary>
[ConfigurationProperty("productcode", IsRequired = false)]
public string ProductCode
{
get
{
return (string)this["productcode"];
}
set
{
this["productcode"] = value;
}
}

/// <summary>
/// The services attribute is used to specify a code that
identifies the services
/// that this feature installs.
/// </summary>
[ConfigurationProperty("services", IsRequired = false)]
public string Services
{
get
{
return (string)this["services"];
}
set
{
this["services"] = value;
}
}

/// <summary>
/// If this is set to true, we will make check for SQL Server.
/// </summary>
[ConfigurationProperty("requiressql", DefaultValue = false,
IsRequired = false)]
public bool RequiresSql
{
get
{
return (bool)this["requiressql"];
}
set
{
this["requiressql"] = value;
}
}

/// <summary>
/// If this is set to true, we will check for MSMQ.
/// </summary>
[ConfigurationProperty("requiresmsmq", DefaultValue = false,
IsRequired = false)]
public bool RequiresMsmq
{
get
{
return (bool)this["requiresmsmq"];
}
set
{
this["requiresmsmq"] = value;
}
}

/// <summary>
/// The checked attribute defines the default checked state of
this feature.
/// If any of the features is already installed, the checked
features are the
/// ones that are already installed. If none of the features are
installed,
/// we get the checked state from this attribute.
/// </summary>
[ConfigurationProperty("checked", DefaultValue = true, IsRequired
= false)]
public bool Checked
{
get
{
return (bool)this["checked"];
}
set
{
this["checked"] = value;
}
}

/// <summary>
/// Specifies a delay after the command completes.
/// </summary>
[ConfigurationProperty("delay", DefaultValue = 0, IsRequired =
false)]
public int Delay
{
get
{
return (int)this["delay"];
}
set
{
this["delay"] = value;
}
}

public bool IsInstalled
{
get
{
return m_IsInstalled;
}
set
{
m_IsInstalled = value;
}
}
private bool m_IsInstalled;

public override string ToString()
{
return Title;
}
}
}



Now that it is all defined, you can use it like this:

FeatureSection featureSection =
ConfigurationManager.GetSection("features") as FeatureSection;



Thanks for listening!

John Vottero
http://www.JAMSScheduler.com


Thomas Kehl said:
Hello.

I would extend the app.config with the fallowing configSection:

<plugins>
<Test1 active="1" />
<Test2 active="0" />
</plugins>

Now, I don't now, how does I have declare the section and after read the
values with the ConfigManager.
Can anybody help me?

Thanks.

Best Regards, Thomas
 
Hi John
Thank you. Now it works.
Thomas

John said:
In your PluginSection class, the Plugins property should return a
PluginCollection, not a PluginSection.


Thomas Kehl said:
Hi John

Thank you. I have no try this. When I use it, I became a
System.Configuration.ConfigurationErrorsException. The Message is
(translated from german to english):
The property of the configuration can not be derived from
ConfigurationSection.

Here is my app.config the the code:

<configSections>
<section name="plugins"
type="mt.communicationServices.library.PluginSection,
mt.CommunicationServices.Library" />
<plugins>
<plugin name="Test1" active="1"></plugin>
<plugin name="Test2" active="0"></plugin>
</plugins>


using System.Configuration;

namespace mt.communicationServices.library {
public sealed class PluginSection : ConfigurationSection {
[ConfigurationProperty("", IsDefaultCollection = true)]
public PluginSection Plugins {
get { return (PluginSection) base[""]; }
}
}


public sealed class PluginCollection :
ConfigurationElementCollection {
public override ConfigurationElementCollectionType
CollectionType {
get { return ConfigurationElementCollectionType.BasicMap; }
}

protected override ConfigurationElement CreateNewElement() {
return new PluginElement();
}

protected override ConfigurationElement
CreateNewElement(string elementName) {
return new PluginElement(elementName);
}

protected override object GetElementKey(ConfigurationElement
element) {
return ((PluginElement) element).Name;
}

protected override string ElementName {
get { return "plugin"; }
}
}


public sealed class PluginElement : ConfigurationElement {
public PluginElement() {
}

public PluginElement(string newName) {
Name = newName;
}

public PluginElement(string newName, string newActive) {
Name = newName;
Active = newActive;
}

[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name {
get { return (string) this["name"]; }
set { this["name"] = value; }
}

[ConfigurationProperty("active", IsRequired = true)]
public string Active {
get { return (string) this["active"]; }
set { this["active"] = value; }
}

public override string ToString() {
return Name;
}
}
}


can you help me one more time?

Thank you.

Thomas


John said:
First, you need a <configSections> to identify your sections and the
types and assemblies that know how to read your sections, something
like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section
name="features"
type="MySample.FeatureSection, MyAssembly" />
</configSections>

You could have multiple <section> definitions.

That is followed by instances of the sections, like this:

<features>
<feature
name="Client"
title="My Sample Client"
description="An example"
status="Installing Client tools"
productcode="{345BC2AA-A7C1-44c8-9653-AC355E744D8E}"
command="msiexec"
arguments="-i SetupClient.msi &quot;TARGETDIR={0}&quot;" />
<feature
name="Server"
title="My Sample Server"
description="This is a sample"
status="Installing Server"
productcode="{BCD2C3AA-78CB-4662-ABCF-33D53CAADF58}"
command="msiexec"
arguments="-i SetupScheduler.msi &quot;TARGETDIR={0}&quot;
DEFQUAL=&quot;/INSTANCE={1}&quot;"
requiresmsmq="true"
requiressql="true"/>
</features>
</configuration>

In your "MyAssembly" assembly, you have to define the section, like
this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
/// <summary>
/// The FeatureSection class is the starting point for the
features section of
/// our application configuration file. This is a very simple
class because it just
/// needs to identify and return the default collection which is a
FeatureCollection.
/// </summary>
public sealed class FeatureSection : ConfigurationSection
{
public FeatureSection()
{
}

[ConfigurationProperty("", IsDefaultCollection = true)]
public FeatureCollection Features
{
get
{
return (FeatureCollection)base[""];
}
}
}
}



Then, you have to define the FeatureCollection (or PluginCOllection
etc.), like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
public sealed class FeatureCollection :
ConfigurationElementCollection
{
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMap;
}
}

protected override ConfigurationElement CreateNewElement()
{
return new FeatureElement();
}

protected override ConfigurationElement
CreateNewElement(string elementName)
{
return new FeatureElement(elementName);
}

protected override object GetElementKey(ConfigurationElement
element)
{
return ((FeatureElement)element).Name;
}

protected override string ElementName
{
get
{
return "feature";
}
}
}
}


And finally, define the Feature element, like this:

using System;
using System.Collections;
using System.Configuration;
using System.Text;

namespace MySample
{
/// <summary>
/// The FeatureElement class defines the syntax and options that
can be specified in the
/// &lt;Feature&gt; element in the application configuration file.
/// Each &lt;Feature&gt; element defines one feature that the user
can select to install.
/// </summary>
public sealed class FeatureElement : ConfigurationElement
{
public FeatureElement()
{
}

public FeatureElement(string newName)
{
Name = newName;
}

public FeatureElement(string newName, string newDescription,
string newCommand)
{
Name = newName;
Description = newDescription;
Command = newCommand;
}

/// <summary>
/// The name attribute is required and must be unique within
the collection.
/// </summary>
[ConfigurationProperty("name", IsRequired = true, IsKey = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}

/// <summary>
/// The title attribute specifies the text that is in the
feature selection list box.
/// </summary>
[ConfigurationProperty("title", IsRequired=true)]
public string Title
{
get
{
return (string)this["title"];
}
set
{
this["title"] = value;
}
}

/// <summary>
/// The status attribute specifies the text that is displayed
when the feature
/// is being executed. If the text isn't defined, the title
is used.
/// </summary>
[ConfigurationProperty("status", IsRequired = false)]
public string Status
{
get
{
string returnString = (string)this["status"];
if (returnString.Length == 0)
{
returnString = (string)this["description"];
}
return returnString;
}
set
{
this["status"] = value;
}
}

/// <summary>
/// The description attribute specfies the text that is
displayed under the feature
/// selection list box when the feature is the selected
(checked or not).
/// </summary>
[ConfigurationProperty("description", IsRequired = false)]
public string Description
{
get
{
return (string)this["description"];
}
set
{
this["description"] = value;
}
}

/// <summary>
/// The command attribute specifies the command that is
executed to install the feature.
/// You specify either the command or the download URL.
/// </summary>
[ConfigurationProperty("command", IsRequired = false)]
public string Command
{
get
{
return (string)this["command"];
}
set
{
this["command"] = value;
}
}

/// <summary>
/// The arguments attribute specifies the arguments passed to
the command.
/// You can use "{0}" where you want the target directory
substituted.
/// </summary>
[ConfigurationProperty("arguments", IsRequired = false)]
public string Arguments
{
get
{
return (string)this["arguments"];
}
set
{
this["arguments"] = value;
}
}

/// <summary>
/// The sourcefile attribute is used when the command is "copy"
/// </summary>
[ConfigurationProperty("sourcefile", IsRequired = false)]
public string SourceFile
{
get
{
return (string)this["sourcefile"];
}
set
{
this["sourcefile"] = value;
}
}

/// <summary>
/// The destinationfile attribute is used when the command is
"copy"
/// and when downloading a file.
/// </summary>
[ConfigurationProperty("destinationfile", IsRequired = false)]
public string DestinationFile
{
get
{
return (string)this["destinationfile"];
}
set
{
this["destinationfile"] = value;
}
}

/// <summary>
/// The overwrite attribute is used when the command is "copy"
/// </summary>
[ConfigurationProperty("overwrite", DefaultValue = false,
IsRequired = false)]
public bool Overwrite
{
get
{
return (bool)this["overwrite"];
}
set
{
this["overwrite"] = value;
}
}

/// <summary>
/// The productcode is used when the command is msiexec. The
product code is the GUID
/// that identifies this product and we need it to determine
if the product is already installed.
/// If the product is already installed, we add REINSTALL=ALL
and REINSTALLMODE=vomus to the
/// msiexec command.
/// </summary>
[ConfigurationProperty("productcode", IsRequired = false)]
public string ProductCode
{
get
{
return (string)this["productcode"];
}
set
{
this["productcode"] = value;
}
}

/// <summary>
/// The services attribute is used to specify a code that
identifies the services
/// that this feature installs.
/// </summary>
[ConfigurationProperty("services", IsRequired = false)]
public string Services
{
get
{
return (string)this["services"];
}
set
{
this["services"] = value;
}
}

/// <summary>
/// If this is set to true, we will make check for SQL Server.
/// </summary>
[ConfigurationProperty("requiressql", DefaultValue = false,
IsRequired = false)]
public bool RequiresSql
{
get
{
return (bool)this["requiressql"];
}
set
{
this["requiressql"] = value;
}
}

/// <summary>
/// If this is set to true, we will check for MSMQ.
/// </summary>
[ConfigurationProperty("requiresmsmq", DefaultValue = false,
IsRequired = false)]
public bool RequiresMsmq
{
get
{
return (bool)this["requiresmsmq"];
}
set
{
this["requiresmsmq"] = value;
}
}

/// <summary>
/// The checked attribute defines the default checked state of
this feature.
/// If any of the features is already installed, the checked
features are the
/// ones that are already installed. If none of the features
are installed,
/// we get the checked state from this attribute.
/// </summary>
[ConfigurationProperty("checked", DefaultValue = true,
IsRequired = false)]
public bool Checked
{
get
{
return (bool)this["checked"];
}
set
{
this["checked"] = value;
}
}

/// <summary>
/// Specifies a delay after the command completes.
/// </summary>
[ConfigurationProperty("delay", DefaultValue = 0, IsRequired =
false)]
public int Delay
{
get
{
return (int)this["delay"];
}
set
{
this["delay"] = value;
}
}

public bool IsInstalled
{
get
{
return m_IsInstalled;
}
set
{
m_IsInstalled = value;
}
}
private bool m_IsInstalled;

public override string ToString()
{
return Title;
}
}
}



Now that it is all defined, you can use it like this:

FeatureSection featureSection =
ConfigurationManager.GetSection("features") as FeatureSection;



Thanks for listening!

John Vottero
http://www.JAMSScheduler.com


Hello.

I would extend the app.config with the fallowing configSection:

<plugins>
<Test1 active="1" />
<Test2 active="0" />
</plugins>

Now, I don't now, how does I have declare the section and after read
the values with the ConfigManager.
Can anybody help me?

Thanks.

Best Regards, Thomas
 
Back
Top