b2aat6n
b2aat6n
b2aat6n
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
[Abb. 3] DebugView zeigt die Trace-Ausgaben.<br />
Hier stellte sich mir die Frage, wie man am<br />
einfachsten überprüft, ob der Dienst tatsächlich<br />
gestartet und gestoppt werden<br />
kann. Eine Ausgabe auf der Konsole scheidet<br />
aus, denn schließlich handelt es sich<br />
um einen Dienst ohne Benutzerinteraktion.<br />
Ich entschied mich für eine Ausgabe<br />
mittels System.Diagnostics.Trace aus dem<br />
.NET Framework. Diese kann nämlich mit<br />
dem Programm DebugView aus der SysInternals-Sammlung<br />
[4] angezeigt werden.<br />
Damit Trace-Ausgaben von Diensten angezeigt<br />
werden, muss im DebugView die Einstellung<br />
„Capture Global Win32“ aktiviert<br />
werden. Voraussetzung dafür ist wiederum,<br />
dass das Programm mit Administratorrechten<br />
gestartet wird. Abbildung 3 zeigt<br />
die Ausgabe von DebugView.<br />
Die Features F2 und F3 zu ergänzen ist<br />
dank der EBCs ganz leicht. Dazu musste<br />
ich lediglich die Auswertung der Argumente<br />
so ergänzen, dass weitere Kommandozeilenparameter<br />
erkannt werden. Das Ausführen<br />
des Dienstes von der Konsole aus,<br />
also ohne Installation im Betriebssystem,<br />
war ganz leicht und benötigte keine weitere<br />
Funktionseinheit. Für das Starten und<br />
Stoppen des Dienstes habe ich die Klasse<br />
ServiceStarter ergänzt. Anschließend konnte<br />
ich in der Klasse EasyService die Verdrahtung<br />
ergänzen, und das neue Feature war<br />
fertig.<br />
Fazit<br />
Bei dieser Übung ist die Testabdeckung<br />
recht gering ausgefallen. Dies hat mich natürlich<br />
nicht kaltgelassen. Allerdings gibt es<br />
zwei Dinge zu berücksichtigen: Zum einen<br />
wären automatisierte Tests aufgrund des<br />
sehr hohen Infrastrukturanteils sehr aufwendig,<br />
darauf habe ich weiter oben an<br />
den entsprechenden Stellen bereits hingewiesen.<br />
Zum anderen sorgt die hier vorgestellte<br />
Dienstinfrastruktur aber dafür, dass<br />
der eigentliche Kern des zu implementierenden<br />
Dienstes völlig befreit ist von Infrastrukturabhängigkeiten.<br />
Dadurch ist der<br />
Kern des Dienstes besser zu testen. Insofern<br />
kann ich akzeptieren, dass der Infrastrukturanteil<br />
mittels manueller Integra-<br />
Listing 11<br />
Die Administratorberechtigung anfordern.<br />
tionstests überprüft wird. Die Vorgehensweise,<br />
ausgehend von einer Featureliste<br />
über die EBC-Architektur hin zur Implementierung,<br />
hat sich bewährt. Wie sah das<br />
bei Ihnen aus? Schreiben Sie doch einmal<br />
einen Leserbrief zu Ihren Erfahrungen<br />
beim dotnetpro dojo! [ml]<br />
[1] Ralf Westphal, Zusammenstecken – funktioniert,<br />
Event-Based Components, dotnetpro 6/2010,<br />
LÖSUNG<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Listing 12<br />
Den Service installieren und entfernen.<br />
public class ServiceInstallation : IServiceInstallieren, IServiceDeinstallieren<br />
{<br />
public void In_Installieren(ServiceBeschreibung name) {<br />
var transactedInstaller = CreateTransactedInstaller(name, "Install.log");<br />
transactedInstaller.Install(new Hashtable());<br />
}<br />
}<br />
public void In_Deinstallieren(ServiceBeschreibung name) {<br />
var transactedInstaller = CreateTransactedInstaller<br />
(name, "UnInstall.log");<br />
transactedInstaller.Uninstall(null);<br />
}<br />
private static TransactedInstaller CreateTransactedInstaller<br />
(ServiceBeschreibung name, string logFilePath) {<br />
var serviceProcessInstaller = new ServiceProcessInstaller {<br />
Account = ServiceAccount.LocalSystem<br />
};<br />
}<br />
var transactedInstaller = new TransactedInstaller();<br />
transactedInstaller.Installers.Add(serviceProcessInstaller);<br />
var path = string.Format("/assemblypath={0}",<br />
Assembly.GetEntryAssembly().Location);<br />
var installContext = new InstallContext(logFilePath, new[] {path});<br />
transactedInstaller.Context = installContext;<br />
var serviceInstaller = new ServiceInstaller {<br />
ServiceName = name.Name,<br />
DisplayName = name.DisplayName,<br />
Description = name.Description<br />
};<br />
transactedInstaller.Installers.Add(serviceInstaller);<br />
return transactedInstaller;<br />
S. 132ff., www.dotnetpro.de/<br />
A1006ArchitekturKolumne<br />
[2] Ralf Westphal, Stecker mit System,<br />
dotnetpro 7/2010, S. 126ff.,<br />
www.dotnetpro.de/A1007ArchitekturKolumne<br />
[3] Ralf Westphal, Nicht nur außen schön,<br />
dotnetpro 8/2010, S. 126ff.,<br />
www.dotnetpro.de/A1008ArchitekturKolumne<br />
[4] DebugView for Windows v4.76,<br />
www.dotnetpro.de/SL1011dojoLoesung1<br />
www.dotnetpro.de dotnetpro.dojos.2011 49