über mich
mein motto

Visual C# 2008 - Das Videotraining von Lars Keller

followme

Get your 'feeds' on Follow me on Twitter Currently no podcasts available

recentcomments

Comment RSS

community

Community Leader / Insider Program VSTO Taskforce Just Community .NET Developer Group Braunschweig

ConfigurationSection in Action

27. Januar 2008 | .NET Entwicklung 2

Seit dem .NET Framework 2.0 gibt es neue Möglichkeiten, eigene ConfigurationSection für eine App.config zu implementieren. Früher musste dazu das System.Configuration.IConfigurationSectionHandler Interface abgeleitet werden, welches aber nun deprecated ist. Nun bot sich für meine kleine StartUp-Applikation an, die ConfigurationSection zu benutzen.

Mich hat schon länger das Bootverhalten meines Rechners genervt. Alle Programme starten gleichzeitig, das kann man doch tunen! Aus diesem Grunde habe ich mir eine kleine StartUp-Applikation erstellt, welche Programme nach einer bestimmen Zeit nacheinander startet. Dazu habe ich mir meine eigene App.config Section überlegt. Der schnellste Weg ohne eine eigene ConfigurationSection wäre mit NameValueCollection gewesen. NameValueCollection verwaltet aber nur einen Key und ein Attribut und gerade wenn man mit mehr als Attributen arbeiten will, bietet sich eine eigene ConfigurationSection an. Auf geht es!

Folgende XML Struktur soll die ConfigurationSection einlesen:

App.config - Copy Code
1<programSettings> 2 <programToStart delayBeforeStartSeconds="0"> 3 <programToStartList > 4 <add programName="test.exe" startNextDelaySeconds="0"/> 5 <add programName="test1.exe" startNextDelaySeconds="0" 6 startOption="/startup" /> 7 </programToStartList> 8 </programToStart> 9</programSettings>

Es gibt folgende Attribute:

delayBeforeStartSeconds Gibt an, wie lange die Applikation warten soll, bis das erste Programm gestartet wird
programName Programmname des zu startenden Programms
startNextDelaySeconds Gibt die Wartezeit an, bis das nächste Programm gestartet werden soll
startOption Falls das Programm Startoptionen hat, können die hier hinterlegt werden.


Was benötigen wir noch? Wir brauchen eine ConfigurationSection-Klasse, eine ConfigurationElement-Klasse, welche die Attribute ausliest und eine ConfigurationElementCollection-Klasse, die die Iteration über die einzelnen ConfigurationElemente übernimmt.

Als erstes müssen wir eine Klasse (ProgramToStartConfiguration) erstellen, dazu müssen wir von der
ConfigurationSection-Klasse ableiten:

ConfigurationSection - Klasse - Copy Code
1 public class ProgramToStartConfiguration : ConfigurationSection 2 { 3 private ConfigurationPropertyCollection _properties; 4 5 private ConfigurationProperty _programToStartList; 6 private readonly ConfigurationProperty _delayBeforeStartSeconds; 7 8 public ProgramToStartConfiguration() 9 { 10 _programToStartList = new
                  ConfigurationProperty(
"programToStartList",
                                             typeof(ProgramToStartList)); 11 _delayBeforeStartSeconds = 12 new ConfigurationProperty("delayBeforeStartSeconds", 13 typeof(int), (int)1000, 14 ConfigurationPropertyOptions.None); 15 _properties = 16 new ConfigurationPropertyCollection(); 17 18 _properties.Add(_programToStartList); 19 _properties.Add(_delayBeforeStartSeconds); 20 21 } 22 23 [IntegerValidator(MinValue = 1, MaxValue = 10000, 24 ExcludeRange = false)] 25 public int TimeBeforeStart 26 { 27 get { return (int)this["delayBeforeStartSeconds"]; } 28 set { this["delayBeforeStartSeconds"] = value; } 29 } 30 [ConfigurationProperty("programToStartList")] 31 public ProgramToStartList ProgramToStartList 32 { 33 get { return base[_programToStartList] as ProgramToStartList; } 34 } 35 36 protected override ConfigurationPropertyCollection Properties 37 { 38 get { return _properties; } 39 } 40 }

Wie man in der XML Darstellung (s. Zeile 2) sehen kann, ist die ConfigurationSection als "programToStart" bezeichnet
und enthält das Attribut "delayBeforeStartSeconds". Damit wir das Attribut auslesen können, müssen wir ein passendes ConfigurationProperty (s. Zeile 12-15) erstellen. Damit wir das Property ansprechen können, müssen wir es noch nach außen hin sichtbar machen (s. Zeile 24-30). Passend dazu habe ich einen IntegerValidator erstellt, da der Wert der benötigten Zahl zwischen 1 und 10000 liegen soll. Was jetzt noch fehlt, ist die ConfigurationPropertyCollection zur Verwaltung der Properties.

In Zeile 3-6 der XML Section ist eine Auflistung von mehreren Elementen zu sehen. Damit wir so eine Auflistung als Collection erstellen können, muss die ConfigurationElementCollection-Klasse (ProgramToStartList) erstellt werden:

ConfigurationElementCollection - Klasse - Copy Code
1 public class ProgramToStartList : ConfigurationElementCollection 2 { 3 protected override ConfigurationElement CreateNewElement() 4 { 5 return new ProgramToStart(); 6 } 7 8 protected override object GetElementKey(ConfigurationElement element) 9 { 10 if (element is ProgramToStart) 11 return ((ProgramToStart) element).ProgramName; 12 else 13 throw new ArgumentException("The specified element is 14 not of the correct type."); 15 } 16 }


Die Klasse erfordert die beiden Methoden CreateNewElement() und GetElementKey(). Damit die Attribute von einem Element ausgelesen werden können, benötigen wir noch eine ConfigurationElement-Klasse:

ConfigurationElement - Klasse - Copy Code
1 public class ProgramToStart : ConfigurationElement 2 { 3 private ConfigurationPropertyCollection _properties; 4 private readonly ConfigurationProperty _programName; 5 private readonly ConfigurationProperty _startNextDelaySeconds; 6 private readonly ConfigurationProperty _startOption; 7 8 protected override ConfigurationPropertyCollection Properties 9 { 10 get { return this._properties; } 11 } 12 13 public ProgramToStart() 14 { 15 _programName = new ConfigurationProperty("programName", 16 typeof (string),"", 17 ConfigurationPropertyOptions.IsRequired); 18 _startNextDelaySeconds = 19 new ConfigurationProperty("startNextDelaySeconds", 20 typeof (int), (int) 1000, 21 ConfigurationPropertyOptions.None); 22 _startOption = new ConfigurationProperty("startOption", 23 typeof(string), ""); 24 _properties = 25 new ConfigurationPropertyCollection(); 26 27 _properties.Add(_programName); 28 _properties.Add(_startNextDelaySeconds); 29 _properties.Add(_startOption); 30 } 31 32 [IntegerValidator(MinValue = 1, MaxValue = 10000, 33 ExcludeRange = false)] 34 public int StartNextDelaySeconds 35 { 36 get { return (int) this["startNextDelaySeconds"]; } 37 set { this["startNextDelaySeconds"] = value; } 38 } 39 40 public string ProgramName 41 { 42 get { return this["programName"].ToString(); } 43 set { this["programName"] = value; } 44 } 45 public string StartOption 46 { 47 get { return this["startOption"].ToString(); } 48 set { this["startOption"] = value; } 49 } 50 }

Die Elementklasse "ProgramToStart" hat denselben Aufbau (ConfigurationProperty, ConfigurationPropertyCollection) wie der, der schon weiter oben diskutiert worden ist.

Das war es schon! Wenn wir unsere eigene ConfigurationSection in unserer Applikation auslesen wollen, machen wir das über die ConfigurationManager.GetSection() Methode:

1 ProgramToStartConfiguration conf = 2 ConfigurationManager.GetSection("programSettings/programToStart") 3 as ProgramToStartConfiguration;

Das Erweitern der ConfigurationSection um ein weiteres Attribut ist relativ einfach, da man nur in der Klasse ein weiteres ConfigurationProperty hinzufügen muss. Es greift dann der größere Aufwand beim Erstellen einer eigenen ConfigurationSection.

Installation des Tools: Einfach die StartAfterBootUp.exe in den Autostart legen und mit der App.Config konfigurieren.

Links:

StartAfterBootUp: Exe
StartAfterBootUp: Sourcecode

kick it on dotnet-kicks.de

Kommentare

28.01.2008 13:50:47 #

Alexander Groß | Antwort

Alexander Groß

Unter Windows Vista erledige ich das über geplante Tasks die bei der Anmeldung eines Benutzers gestartet werden. Hier gibt es auch schöne UI die es ermöglicht die "Autostart"-Tasks zu gruppieren.

29.01.2008 11:26:11 #

Lars Keller | Antwort

Lars Keller

Hi Alex,
davon habe ich gehört, aber als Windows XP Benutzer muss man da noch tricksen Wink

Grüße
Lars

Kommentar schreiben


(Zeigt dein Gravatar icon)

biuquote
  • Kommentar
  • Live Vorschau
Loading