Dienste programmieren mit .NET

Hilfe-Tools: Das InstallUtil

Nach dem Kompilieren des Projekts geht die Komplexität aber gleich weiter. Beim Versuch, das fertige Programm zu starten, erhalten Sie eine Fehlermeldung: Das Programm kann ohne Installation nicht gestartet werden, da der Dienst dem Service Control Manager nicht bekannt ist. Das gilt auch für das Debuggen: Man kann das Programm nicht einfach so debuggen. Stattdessen muss man den Dienst installieren, starten und sich dann vom Debugger aus mit dem Dienst verbinden.

Die Installation des Dienstes erfolgt mit dem Programm InstallUtil aus dem .NET Framework. Nur geht auch das nicht ohne Weiteres. InstallUtil ist zwar in der Lage, .NET Assemblies zu installieren - auch solche, die Windows-Dienste beinhalten -dazu braucht es aber noch ein paar weitere Informationen: Schließlich kann InstallUtil nicht raten, was für eine Art Dienst installiert werden soll.

Um diese Informationen unterzubringen, benötigt man eine ProjectInstaller-Komponente. Sie setzt sich aus einem ServiceProjectInstaller und einem ServiceInstaller zusammen. Der Grund dafür ist einfach: Ein Service-Projekt kann mehrere Dienste beinhalten. Darum muss man für das Projekt einen Installer haben, der die Informationen über die ausführbare Datei enthält. Ferner braucht man für jeden Service im Projekt einen ServiceInstaller, der die Informationen über den spezifischen Dienst enthält. Die Vorlagen für diese Komponenten sind übrigens nur in der Professional-Variante von Visual Studio enthalten.

Man kann das Projekt ganz einfach um die benötigten Komponenten erweitern, indem man in den Eigenschaften der Service-Komponente auf "AddInstaller" klickt. Dadurch erscheint eine neue Komponente in der Solution-Ansicht. In der Designer-Ansicht der Komponente kann man dann die Eigenschaften des ProjectInstaller und des ServiceInstaller bearbeiten.

Hier ist hauptsächlich der ServiceInstaller von Interesse. Er benötigt einen sinnvollen Namen (DisplayName), der dann später beispielsweise im Dienste-Applet der Systemsteuerung angezeigt wird. Ferner muss man einen eindeutigen internen Namen (ServiceName) vergeben, unter dem der Dienst identifizierbar ist. Dieser wird zum Beispiel verwendet, wenn per Kommandozeile (net start) auf den Dienst zugegriffen wird. Schließlich kann man hier auch noch den Starttyp des Dienstes und die Abhängigkeiten von anderen Diensten angeben.