8.3 Konfigurationsdateien 

Die Common Language Runtime (CLR) wertet Konfigurationsdateien beim Start einer Anwendung aus. Während des Laufs können Sie über Programmcode darauf zugreifen. Sie ersetzen Einstellungen in der Registry oder in INI-Dateien. Der Inhalt dieser Dateien wird von den Anforderungen der Anwendung bestimmt, zum Beispiel Verbindungszeichenfolgen für ADO.NET und Angaben über die zu verwendende Version einer Bibliothek.
Für Anwendungen auf der lokalen Maschine gibt es drei Arten Konfigurationsdateien: Anwendungskonfigurationsdateien, Herausgeberrichtliniendateien und Maschinenkonfigurationsdatei (machine.config). Unser Fokus liegt auf der ersten Art, die aus zwei Gruppen unterschiedlicher Daten besteht:
- Anwendungsdaten, die benutzerunabhängig für die gesamte Anwendung gültig sind
- Daten, die benutzerspezifisch sind
Konfigurationsdateien sind XML-Dateien. XML (Extended Markup Language) ist ein klar definierter Standard, der nicht dieselbe Lässigkeit wie HTML erlaubt. Zum Beispiel müssen Tags immer geschlossen werden, und es wird zwischen Groß- und Kleinschreibung unterschieden.
8.3.1 Die verschiedenen Konfigurationsdateien 

Namen von Konfigurationsdateien enden typischerweise auf config. Im Wesentlichen gibt es drei Arten, die in folgender Reihenfolge nach Einstellungen durchsucht werden:
- Anwendungskonfigurationsdateien: Sie sind optional. Wenn sie existieren, dann immer im Stammverzeichnis der Anwendung, und sie leiten ihren Namen aus der Anwendung ab. (MyApp.exe hat die Konfigurationsdatei MyApp.exe.config.) Ihre Einstellungen wirken sich nur auf diese Anwendung aus.
- Publisherrichtliniendateien (Herausgeberrichtliniendateien): Sie sind ebenfalls optional und regeln die automatische Umleitung von Aufrufen einer älteren Version einer GAC-Assembly auf eine neuere.
- Maschinenkonfigurationsdatei: Standardmäßig unter \Windows\Microsoft .NET\Framework\v<Versionsnummer>\Config\machine.config installiert, enthält die Maschinenkonfigurationsdatei viele .NET-weite Einstellungen. Die Datei ist erforderlich.
Bei der Suche nach einer gültigen Einstellung wird zuerst das Manifest ausgewertet. Danach werden die drei Konfigurationsdateien in der angegebenen Reihenfolge durchsucht. Jede darf die Einstellungen vorheriger überschreiben, nach dem Motto »Der Letzte gewinnt«.
Durch einen Umweg kann dieser Mechanismus »ausgehebelt« werden. Zum Beispiel kann der Automatismus der Versionsumleitung in der Anwendungskonfigurationsdatei abgeschaltet werden. Wird die Abschaltung selbst nicht durch eine der folgenden Konfigurationsdateien wieder abgeschaltet (d. h. Umleitung ein), ist eine in folgenden Konfigurationsdateien geänderte Versionsumleitung wirkungslos (wegen der Abschaltung). Die Abschaltung ist zum Beispiel sinnvoll, wenn machine.config sonst eine inkompatible Version erzwingen würde.
8.3.2 Struktur einer Anwendungskonfigurationsdatei 

Da Konfigurationsdateien reiner XML-Code sind, können Sie sie in einem beliebigen Editor erstellen. Über den Kontextmenüpunkt Hinzufügen... • NeuesElement hinzufügen|Anwendungskonfigurationsdatei eines Projekts können Sie sich einen Rahmen erstellen lassen. Den gewählten Namen app.config dürfen Sie nicht ändern. Die Kompilierung ändert den Namen im Ausgabeverzeichnis automatisch.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
...
</configuration>
Die XML-Deklaration in der ersten Zeile legt die Versionsnummer und den zum Lesen des Dokuments verwendeten Zeichensatz fest, hier UTF-8. Alle Einstellungen stehen innerhalb des fest vorgegebenen Wurzelelements <configuration>. Anhand des folgenden (gekürzten) Beispiels möchte ich ein paar Einstellungen ansprechen.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" ...>
<section name="GacAnwendung.My.MySettings" .../>
</sectionGroup>
<sectionGroup name="applicationSettings" ...>
<section name="GacAnwendung.My.MySettings" .../>
</sectionGroup>
</configSections>
<appSettings>
<add key="Test" value="123"/>
</appSettings>
<userSettings>
<GacAnwendung.My.MySettings>
<setting name="Variable1" serializeAs="String">
<value>Hallo Morph!</value>
</setting>
</GacAnwendung.My.MySettings>
</userSettings>
<applicationSettings>
<GacAnwendung.My.MySettings>
<setting name="Variable2" serializeAs="String">
<value>Hallo Sprache!</value>
</setting>
</GacAnwendung.My.MySettings>
</applicationSettings>
</configuration>
Innerhalb von <configuration> sind vier Sektionen definiert:
- <configSections>: Sie fasst die beiden untergeordneten Sektionen <applicationSettings> und <userSettings> zusammen.
- <applicationSettings>: Diese Sektion enthält benutzerunabhängige Daten. Sie entsprechen einer öffentlich deklarierten Eigenschaft, die mit ReadOnly schreibgeschützt ist. Durch die Änderung eines Wertes in der Konfigurationsdatei wird ein Variablenwert ohne Neukompilierung geändert.
- <userSettings>: Hier werden benutzereigene Einstellungen abgelegt. Sie dürfen im Code geändert werden. Die neuen Werte werden in der Datei Dokumente und Einstellungen\ <Benutzer>\Lokale Einstellungen\Anwendungsdaten\<Firma>\\<Anwendung>\<Version>\user.config gespeichert.
- <appSettings>: Der Abschnitt erfüllt die gleiche Aufgabe wie die Sektion <application-Settings>, kann jedoch aus dem Code der laufenden Anwendung heraus editiert werden.
Die Notation der beiden Abschnitte <applicationSettings> und <userSettings> ist identisch. Jedem Element entspricht eine Klasse, im Beispiel die Klasse MySettings im Namensraum GacAnwendung.My. Die Namen werden von Visual Studio automatisch erzeugt, wenn Sie eine Eigenschaft auf der Karteikarte Einstellungen der Projekteigenschaften eintragen.
Die untergeordneten <setting>-Elemente beschreiben mit dem Attribut name den Bezeichner der gespeicherten Variablen, und serializeAs gibt den Datentyp an. Meist werden die Daten als Zeichenfolge serialisiert, ansonsten sind auch noch xml, binary und custom mögliche Alternativen. Das Tag <value> schließlich beschreibt den gespeicherten Wert.
8.3.3 Anwendungskonfigurationsdatei automatisch erstellen 

Wenn Sie auf der Karteikarte Einstellungen in den Projekteinstellungen Werte eintragen, wird gegebenenfalls eine Anwendungskonfigurationsdatei app.config erzeugt und entsprechend den von Ihnen gemachten Einträgen befüllt. In der Spalte Name tragen Sie den Namen der Variablen ein, und unter Typ legen Sie deren Datentyp fest. Die Dropdown-Liste Bereich legt fest, ob die Einstellung anwendungsweit gilt oder benutzerspezifisch ist. In der letzten Spalte können Sie einen Startwert angeben. Abbildung 8.11 zeigt die Einstellungen für die weiter oben gezeigte Anwendungskonfigurationsdatei.
Abbildung 8.11 Festlegen der Konfigurationseinstellungen im Visual Studio
Möchten Sie noch weitere Sektionen festlegen, beispielsweise <appSettings>, öffnen Sie app.config und nehmen die Ergänzung manuell vor. IntelliSense unterstützt Sie dabei.
8.3.4 Anwendungskonfiguarionsdatei auswerten 

Das folgende Beispiel setzt die Bibliothek System.Configuration.dll voraus und wertet die Anwendungskonfiguarionsdatei aus. Die drei Sektionen <appSettings>, <application-Settings> und <userSettings> werden ausgelesen, und den Variablen in <appSettings> und <userSettings> werden neue Werte zugewiesen.
'...\Applikation\Einstellungen\Einstellungen.vb |
Imports System.Configuration
Imports System.Collections.Specialized
Namespace Einstellunegn
Module Einstellungen
Sub Main()
' <userSettings> und <applicationSettings> auswerten
Dim setting As New My.MySettings()
Console.WriteLine("Variable1 = {0}", setting.Variable1)
Console.WriteLine("Variable2 = {0}", setting.Variable2)
' <appSettings> auswerten
Dim col As NameValueCollection = ConfigurationManager.AppSettings
For i As Integer = 0 To col.Count – 1
Console.WriteLine("Name: {0} – Wert: {1}", col.Keys(i), col(i))
Next
' <userSettings> neuen Wert zuordnen
setting.Variable1 = "Bonjour langue!"
setting.Save()
' <appSettings> einen anderen Wert zuweisen
col("Test") = "Aachen"
Console.WriteLine("Test (neu): {0}", col("Test"))
Console.ReadLine()
End Sub
End Module
End Namespace
Die Datei Settings.Designer.vb im Knoten My Project im Projektmappenexplorer definiert die Klasse MySettings, die von System.Configuration.ApplicationSettingsBase abgeleitet ist. Die Datei wird automatisch von Visual Studio generiert. Die Klasse ist das Bindeglied zur Konfigurationsdatei und definiert pro Einstellung eine Instanzeigenschaft. Anwendungsweit gültige Instanzeigenschaften sind mit ReadOnly schreibgeschützt.
Schauen wir uns nun die beiden folgenden Anweisungen an:
setting.Variable1 = "Hallo Peter!";
setting.Save();
Variable1 gehört zu der Sektion <userSettings>. Während beim ersten Aufruf noch der Inhalt Hallo Morph! lautet, wird dieser nach der Konsolenausgabe geändert. Das bewirkt, dass die Zeichenfolge Bonjour langue! in die Datei user.config geschrieben wird, die unter Dokumente und Einstellungen\<Benutzer>\Lokale Einstellungen\Anwendungsdaten\<Firma>\<Anwendung>\<Version> zu finden ist. Der Inhalt lautet:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<userSettings>
<AppConfigDemo.Properties.Settings>
<setting name="Variable1" serializeAs="String">
<value>Bonjour langue!</value>
</setting>
</AppConfigDemo.Properties.Settings>
</userSettings>
</configuration>
Bei allen folgenden Aufrufen wird anschließend immer die benutzerbezogene Zeichenfolge angezeigt.
Noch eine Bemerkung zur Klasse MySettings: Wenn Sie auf die Schaltfläche Code anzeigen auf der Karteikarte Einstellungen der Projekteigenschaften klicken, wird die partielle Klasse mit ein paar Kommentaren angezeigt. Sie weisen auf die Möglichkeit hin, Ereignishandler zu registrieren, die beim Laden, Ändern und Speichern der Eigenschaften ausgelöst werden.
Configuration und ConfigurationManager
Die beiden Klassen im Namensraum System.Configuration (benötigt Verweis auf System.Configuration.dll) dienen dazu, Konfigurationsdateien auszuwerten und zu ändern. Die erste Klasse gibt es seit .NET 2.0, die zweite seit 1.0.
Über die ConfigurationManager-Klasse können Sie auf Maschinen- und Anwendungskonfigurationsinformationen zugreifen (siehe Tabelle 8.2). Die beiden einzigen Eigenschaften ermöglichen den Zugriff auf die Abschnitte <appSettings> und <connectionStrings>.
Eigenschaft | Zugriff auf Abschnitt der Konfigurationsdatei |
AppSettings |
<appSettings> der Standardkonfiguration |
ConnectionStrings |
<connectionStrings> der Standardkonfiguration |
Tabelle 8.3 zeigt die wichtigsten Methoden der Klasse.
Methode | Beschreibung |
GetSection |
Liefert den angegebenen Konfigurationsabschnitt der Standardkonfiguration. |
OpenExeConfiguration |
Öffnet die angegebene Datei als Configuration-Objekt. |
OpenMachineConfiguration |
Öffnet die Computerkonfiguration als Configuration-Objekt. |
RefreshSection |
Aktualisiert den benannten Abschnitt. |
Configuration repräsentiert die Einstellungen einer Anwendung oder des Computers. Die Werte berücksichtigen die Überschreibung von Anwendungseinstellungen durch machine.config. Die Klasse hat keine öffentlichen Konstruktoren, und die Fabrikmethoden OpenExeConfiguration und OpenMachineConfiguration der Klasse ConfigurationManager liefern Instanzen der Klasse Configuration.
Mit seinen Eigenschaften und Methoden greifen Sie auf Sektionen bzw. Sektionsgruppen, den physikalischen Pfad der Konfigurationsdatei und Einstellungen zu. In Tabelle 8.4 und Tabelle 8.5 sind die wichtigsten Eigenschaften und Methoden aufgeführt.
Eigenschaft | Beschreibung |
AppSettings |
Konfigurationsabschnitt des AppSettingsSection-Objekts |
ConnectionStrings |
ConnectionStringsSection-Konfigurationsabschnittsobjekt |
FilePath |
Physikalischer Pfad zur Konfigurationsdatei |
Locations |
Die in diesem Configuration-Objekts definierten Speicherorte |
RootSectionGroup |
Die Stamm-ConfigurationSectionGroup |
SectionGroups |
Auflistung der in der Konfiguration definierten Abschnittsgruppen |
Sections |
Auflistung der von dieser Konfiguration definierten Abschnitte |
Methode | Beschreibung |
GetSection |
Gibt das angegebene ConfigurationSection-Objekt zurück. |
GetSectionGroup |
Ruft das angegebene ConfigurationSectionGroup-Objekt ab. |
Save |
Sichert die Konfiguration als XML in die aktuelle Datei. |
SaveAs |
Sichert die Konfiguration als XML in die angegebene Datei. |
Wie Sie die Klassen Configuration und ConfigurationManager einsetzen können, zeige ich Ihnen im folgenden Abschnitt.
8.3.5 Editierbare, anwendungsbezogene Einträge mit <appSettings> 

Anwendungsweite Einstellungen können Sie ändern, wenn sie im Abschnitt <appSettings> stehen. Das folgende Beispiel zeigt, wie Configuration und ConfigurationManager auf diesen Abschnitt zugreift.
Einträge, die Sie in der Anwendungskonfigurationsdatei im Abschnitt <application-Settings> vornehmen, sind nicht editierbar – zumindest aus dem Code einer Anwendung heraus. Man kann die Werte jedoch jederzeit ändern, indem man die Datei mit einem beliebigen Editor öffnet. Das ist insofern sinnvoll, als dass nicht ein Benutzer von den Änderungen eines anderen Benutzers abhängig gemacht wird.
Nichtsdestotrotz könnten Sie als Entwickler auch einmal in die Situation kommen, aus dem Code heraus eine anwendungsweite Einstellung ändern zu wollen oder eine neue hinzuzufügen. Das kann nur in der Sektion <appSettings> erfolgen. Das folgende Beispiel AppSettingsDemo zeigt, wie Sie mit den Klassen Configuration und ConfigurationManager die Einstellungen in <appSettings> beeinflussen können.
'...\Applikation\AnwendungsEinstellungen\AnwendungsEinstellungen.vb |
Imports System.Configuration
Imports System.Collections.Specialized
Namespace Applikation
Module AnwendungsEinstellungen
Sub ShowAppSettings()
Dim appStgs As NameValueCollection = ConfigurationManager.AppSettings
For i As Integer = 0 To appStgs.Count – 1
Console.WriteLine("Nr. {0} – Wert: {1}", i, appStgs(i))
Next
End Sub
Sub Main()
Console.WriteLine("Ursprüngliche 'appSettings'-Werte:")
ShowAppSettings()
Console.WriteLine(Environment.NewLine & "Hinzufügen eines Eintrags:")
' Bezeichner des Eintrags festlegen
Dim entry As String = "Nr" & ConfigurationManager.AppSettings.Count
' 'appSettings'-Eintrag hinzufügen
Dim cfg As Configuration = ConfigurationManager. _
OpenExeConfiguration(ConfigurationUserLevel.None)
cfg.AppSettings.Settings.Add(entry, Now.ToLongTimeString())
' Ändern des ersten Eintrags
If cfg.AppSettings.Settings.Count > 2 Then cfg.AppSettings.Settings( _
"Nr" & (cfg.AppSettings.Settings.Count – 3)).Value = "veraltet"
' Speichern aller Änderungen
cfg.Save(ConfigurationSaveMode.Modified)
' Erneutes Auslesen der Sektion 'appSettings'
ConfigurationManager.RefreshSection("appSettings")
Console.WriteLine(Environment.NewLine & "Neue 'appSettings'-Werte:")
ShowAppSettings()
' Anzeige des letzten Eintrags in der Konfigurationsdatei
Console.WriteLine(Environment.NewLine & _
"Letzter Eintrag: {0}", ConfigurationManager.AppSettings(entry))
Console.ReadLine()
End Sub
End Module
End Namespace
Beim Start aus der Entwicklungsumgebung heraus wird App.config vor jedem Start restauriert, sodass Sie den Effekt der Sicherung nicht sehen können. Die folgende Ausgabe ergibt sich beim vierten Start innerhalb einer Eingabeaufforderung:
Ursprüngliche 'appSettings'-Werte:
Nr. 0 – Wert: veraltet
Nr. 1 – Wert: 21:44:21
Nr. 2 – Wert: 21:44:25
Hinzufügen eines Eintrags:
Neue 'appSettings'-Werte:
Nr. 0 – Wert: veraltet
Nr. 1 – Wert: veraltet
Nr. 2 – Wert: 21:44:25
Nr. 3 – Wert: 21:46:06
Letzter Eintrag: 21:46:06
Bei jedem Start wird ein zusätzlicher Eintrag mit der Uhrzeit in die Anwendungskonfigurationsdatei geschrieben. Alle Einträge außer den beiden letzten werden als »veraltet« gekennzeichnet«. Die Methode ShowAppSettings durchläuft in einer Schleife die in ConfigurationManager.AppSettings gespeicherten Einstellungen.
Mit OpenExeConfiguration holen wir uns eine Referenz auf die Einstellungen. Deren Auflistung AppSettings.Settings wird mit Add ein neuer Eintrag hinzugefügt und mit Save gespeichert. Die Enumeration ConfigurationSaveMode beschreibt mit Full, Minimal und Modified den zu speichernden Umfang.
8.3.6 Versionsumleitung in einer Konfigurationsdatei 

In Abschnitt 8.2.2, »Globale Assemblies», haben wir dem GAC eine zweite Version der Bibliothek GacBibliothek hinzugefügt. Nun werden wir mittels einer Konfiguration Aufrufe auf die zweite Version umleiten, auch für die bereits erstellte Anwendung GacAnwendung. Dazu erstellen wir im Verzeichnis der Anwendung eine Textdatei namens GacAnwendung.exe.config mit folgendem Inhalt:
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="GacBibliothek"
publicKeyToken="88392D0343E03C8D" />
<publisherPolicy apply="yes" />
<bindingRedirect oldVersion="1.0.0.0"
newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Wenn Sie GacAnwendung starten, zeigt die Ausgabe Zweite Version, dass die Umleitung funktioniert hat – ohne Kompilierung.
Das Element bindingRedirect spezifiziert die Umleitung. Den öffentlichen Schlüssel entnehmen Sie zum Beispiel der Anzeige des GAC (<Windows>\assembly) im Windows Explorer. Jede Bibliothek steht in einem eigenen dependentAssembly-Abschnitt, der außerdem im Element codebase den Speicherort der Bibliothek angeben kann (außerhalb des GAC). Der übergeordnete Abschnitt assemblyBinding kann neben der hier gezeigten Bindung auch noch mit probing und qualifyAssembly die Runtime bei der Suche nach Assemblies unterstützen. Der Abschnitt runtime schließlich kann außerdem Sicherheitsrichtlinien, den Suchpfad für Assemblies und den Garbage Collector beeinflussen.
Was passiert, wenn die Versionsangaben nicht exakt passen? Eine Spezifikation mit einer nicht existierenden alten Version wird schlicht ignoriert, und bei einer falschen neuen Version wird eine Ausnahme FileLoadException ausgelöst. Die Angabe der alten Version kann auch einen ganzen Bereich umfassen, zum Beispiel:
<bindingRedirect oldVersion="3.0.3.0-3.0.7.0" newVersion="3.0.12.0"/>
Alternativ zur manuellen Erstellung gibt es auch eine grafische Oberfläche zur Konfiguration namens Microsoft .NET Framework 2.0-Konfiguration. Sie finden sie im Dialog Verwaltung der Systemsteuerung, die Sie über das Startmenü erreichen. Dort fügen Sie GacAnwendung.exe dem Knoten Arbeitsplatz/Anwendungen hinzu. In dem neu erstellten Knoten markieren Sie den Knoten Verwaltete konfigurierte Assemblys und klicken auf die Schaltfläche Assembly konfigurieren im rechten Fensterteil. Im dann erscheinenden Dialog wählen Sie eine der beiden Versionen von GacBibliothek und bestätigen den Dialog. Im folgenden Dialog aktivieren Sie die Bindungsrichtlinie auf der Karteikarte Allgemein und tragen auf der Karteikarte Bindungsrichtlinie die Versionsumleitung ein – hier von der angeforderten Version 1.0.0.0 zur neuen Version 2.0.0.0.
Hinweis |
Das Verwaltungstool ist seit 2008 nicht mehr Teil von Visual Studio und muss extra installiert werden. |
8.3.7 Die Herausgeberrichtliniendatei 

Da die Herausgeberrichtliniendatei nach der Anwendungskonfigurationsdatei ausgewertet wird (siehe Abschnitt 8.3.1, »Die verschiedenen Konfigurationsdateien«), kann sie deren Einträge überschreiben, zum Beispiel um Versionsumleitungen zu forcieren. Sie wird in kompilierter Form im GAC installiert. Die Kompilierung übernimmt das Kommandozeilentool Assembly Linker al.exe im folgenden Verzeichnis: ...\Programme\Microsoft SDKs\Windows\v6.0A\Bin
Dem Tool wird der Name der Publisherrichtliniendatei, also der XML-Datei, angegeben, der Name der Herausgeberrichtlinienassembly und die Schlüsseldatei der Bibliothek, die Sie beeinflussen wollen.
al /link:<Richtliniendatei> /out:<Ausgabedatei> /keyfile:<SNK-Datei> |
Das Namensformat der Ausgabedatei ist festgelegt:
policy.<Hauptversion>.<Nebenversion>.<betroffene Bibliothek> |
Für unser Beispiel kann das Kommando lauten:
al /link:neu.config /out:policy.1.0.GacBibliothek.dll
/keyfile:TestSchlüssel.snk
Die Herausgeberrichtlinienassembly muss zusammen mit der Assembly im GAC installiert werden. Dazu können Sie wieder das Tool gacutil mit dem Schalter /i benutzen, zum Beispiel:
gacutil /i policy.1.0.GacBibliothek.dll
Alternativ erstellen Sie mit einem Setup-Projekt einen Installer (siehe Abschnitt 8.2.2, »Globale Assemblies»).
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.