Windows Server Advanced Power Management (WSAPM) besitzt eine Plugin-Schnittstelle. Damit kann das Programm auf einfache Art und Weise erweitert und an spezielle Bedürfnisse angepasst und erweitert werden.
In diesem Beitrag soll die Vorgehensweise zur Entwicklung eines einfachen Plugins für Windows Server Advanced Power Management gezeigt werden. Im Unterschied zu einem erweiterten Plugin bietet ein einfaches Plugin keine Einstellungen und Benutzeroberfläche.
Zur Entwicklung kommt Visual Studio 2013 zum Einsatz, die Vorgehensweise sollte aber auch auf andere Entwicklungsumgebungen übertragbar sein. Die Programmiersprache ist C#, man kann aber auch jede andere .NET-Programmiersprache verwenden.
Anforderungen
- Das Plugin soll dafür sorgen, dass der Standby von WSAPM unterdrückt wird, wenn mindestens ein Wechseldatenträger mit dem Computer verbunden ist (z.B. USB-Festplatte oder USB-Stick).
- Das Plugin benötigt keinerlei Einstellungen oder Benutzeroberfläche, daher wird es als einfaches WSAPM-Plugin realisiert.
Voraussetzungen
- Windows Server Advanced Power Management muss bereits installiert sein, da die Installation die DLL enthält, die später im Projekt referenziert werden muss.
Erstellung des Grundgerüsts für das Plugin
Zunächst wird in Visual Studio ein neues Projekt vom Typ Class Library angelegt. Wir nennen das Projekt RemovableDevicesPlugin.

Die automatisch erzeugte Klasse Class1 wird in RemovableDevicesPlugin umbenannt.
Anschließend wird eine Referenz auf die Datei Wsapm.Extensions.dll hinzugefügt.

Diese befindet sich im Installationsordner von Windows Server Advanced Power Management (standardmäßig unter C:\Program Files (x86)\Windows Server Advanced Power Management). Im Reference Manager muss dafür mittels Browse nach der Datei gesucht werden.

Ebenso muss eine Referenz auf System.ComponentModel.Composition hinzugefügt werden. Dies ist eine .NET Framework DLL und kann im Reference Manager unter Assemblies gefunden werden.
Nun folgen die Schritte, um die Klasse in ein WSAPM Plugin zu wandeln: Zunächst wird die Klasse RemovableDevicesPlugin mit dem Attribut WsapmPlugin versehen. Durch dieses Attribut wird Windows Server Advanced Power Management das Plugin als solches erkennen und einbinden. Dazu müssen drei Parameter angegeben werden, die das Plugin beschreiben:
- Der erste Parameter gibt den (internen) Namen des Plugins an. Dieser Name ist nur der interne Name des Plugins und gibt prinzipiell nur den Namen des Orders an, in dem das Plugin installiert wird.
- Der zweite Parameter gibt die Versionsnummer des Plugins an.
- Der letzte Parameter muss eine GUID sein. Diese kann einfach in Visual Studio unter Tools > Create GUID (am besten das Registry Format wählen) erzeugt werden. Es ist sehr wichtig, dass jedes Plugin eine eigene GUID besitzt, da WSAPM die Plugins anhand ihrer GUID unterscheidet. Diese GUID darf sich bei einem Plugin niemals ändern, auch wenn eine neue Version des Plugins erscheint.
Im Rahmen dieser Anleitung werde ich keine konkrete GUID angeben (sondern nur den Platzhalter {YOUR-GUID-HERE}) dass diese nicht kopiert werden kann.
Danach muss noch das Attribut System.ComponentModel.Composition.Export über die Klasse RemovableDevicesPlugin geschrieben werden. Dies sorgt im Grunde genommen dafür, dass die Plugin-DLL dynamisch zur Laufzeit von WSAPM geladen werden kann. Der Parameter definiert das Plugin als WSAPM-Plugin und muss immer typeof(WsapmPluginBase) lauten.
Somit haben wir folgende Klassendefinition:
[Export(typeof(WsapmPluginBase))] [WsapmPlugin("Removable Devices", "v1.0.0", "{YOUR-GUID-HERE}")] public class RemovableDevicesPlugin { }
Als nächstes muss die Klasse von WsapmPluginBase abgeleitet werden. Dies sorgt dafür, dass vier Methoden überschrieben werden müssen:
- Initialize: Diese Methode dient zur Initialisierung des Plugins und wird genau ein mal nach dem Laden des Plugins aufgerufen und kann dazu verwendet werden, einmalige Initialisierungs-Maßnahmen vorzunehmen.
Der Rückgabewert gibt Auskunft darüber, ob die Initialisierung des Plugins erfolgreich abgeschlossen wurde. Wird hier false zurückgeliefert, wurde das Plugin nicht erfolgreich initialisiert (z.B. im Fehlerfall) und wird von WSAPM nicht in die Überprüfungs-Routinen mit einbezogen. Da keine Initialisierung für das Plugin nötig ist, wird hier einfach true zurückgeliefert. - Prepare: Diese Methode wird immer kurz vor der eigentlichen Überprüfungs-Routine aufgerufen und kann dazu verwendet werden, Initialisierungen vorzunehmen, die vor jeder Überprüfung stattfinden müssen.
Der Rückgabewert gibt wiederum Auskunft darüber, ob die Vorbereitung erfolgreich abgeschlossen wurde. Wird hier false zurückgeliefert (z.B. im Fehlerfall), wird WSAPM die Überprüfungs-Routine des Plugins im Folgenden nicht ausführen. Da das Plugin keinerlei Vorbereitungen zur Ausführung der Überprüfungs-Routine benötigt, wird hier einfach true zurückgeliefert. - CheckPluginPolicy: Dies ist die eigentliche Überprüfungs-Routine des Plugins.
Das Ergebnis der Überprüfung wird als PluginCheckSuspendResult zurückgeliefert. Der Konstruktor dieser Klasse erwartet zwei Parameter: Der erste Parameter gibt Auskunft darüber, ob der Standby-Modus von WSAPM unterdrückt werden soll (true: Standby-Modus soll unterdrückt werden; false: Standby-Modus soll nicht unterdrückt werden). Der zweite Parameter ist ein String, welcher den Grund für eine mögliche Unterdrückung des Standby-Modus angibt. Dieser Parameter wird von WSAPM nur ausgewertet, wenn der Standby-Modus tatsächlich unterdrückt werden soll. - TearDown: Diese Methode wird jedes Mal direkt nach der Überprüfung aufgerufen und kann dazu verwendet werden, um notwendige Aufräumarbeiten durchzuführen.
Der Rückgabewert gibt wieder an, ob das Aufräumen erfolgreich beendet wurde. Da das Plugin keine solcher Aufräumarbeiten ausführen muss, wird hier wieder einfach nur true zurückgeliefert.
Implementierung des Plugins
Nachdem das Grundgerüst des Plugins steht, kann die eigentliche Implementierung des Plugins vorgenommen werden. Es wird empfohlen, die Überprüfungs-Logik in eine eigene Klasse auszulagern, damit der technische Plugin-Code vom Code, der die Logik übernimmt, getrennt ist. Dazu fügen wir eine neue Klasse mit dem Namen RemovableDeviceCheck der Solution hinzu. Diese Klasse wird als statische Klasse implementiert, die nur eine Methode besitzt: Die Überprüfung, ob Wechseldatenträger verbunden sind:
/// <summary> /// Class for checking for removable devices. /// </summary> internal static class RemovableDeviceCheck { /// <summary> /// Checks if any removable device is connected to the computer. /// </summary> /// <returns>True, if any removable device is connected to the computer, otherwise false.</returns> internal static bool IsRemovableDeviceConnected() { var removableDevices = DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.Removable); return removableDevices.Count() > 0; } }
Der Aufruf dieser Überprüfungs-Methode erfolgt nun im der Klasse RemovableDevicesPlugin in der Methode CheckPluginPolicy. Somit sieht die Implementierung der Klasse folgendermaßen aus:
/// <summary> /// WSAPM plugin class for supressing standby if any removable devices are present. /// </summary> [Export(typeof(WsapmPluginBase))] [WsapmPlugin("Removable Devices", "v1.0.0", "{YOUR-GUID-HERE}")] public class RemovableDevicesPlugin : WsapmPluginBase { protected override bool Initialize() { return true; } protected override bool Prepare() { return true; } protected override PluginCheckSuspendResult CheckPluginPolicy() { var removableDevicesPresent = RemovableDeviceCheck.IsRemovableDeviceConnected(); // Supress standby if any removable devices are present. var checkResult = new PluginCheckSuspendResult(removableDevicesPresent, "Wechseldatenträger erkannt"); return checkResult; } protected override bool TearDown() { return true; } }
Das Plugin-Manifest
Ein weiterer wichtiger Punkt ist das sog. Plugin-Manifest. Dies ist eine XML-Datei mit weiteren Angaben zum Plugin. Diese Informationen dienen zwei Zwecken: Zum einen werden die Informationen aus dem Manifest an der Oberfläche von WSAPM (Tabe Plugins in den Einstellungen) angezeigt. Zum anderen wird durch das Manifest eine Unterstützung von mehreren Sprachen möglich.
Das Manifest hat einen definierten Aufbau:
<?xml version="1.0" encoding="utf-8" ?> <WsapmPlugin> <DescriptionSet lang="en"> <PluginName>Removable Devices</PluginName> <Description>Plugin for standby suppression if any removable devices are present</Description> <AuthorName>DecaTec</AuthorName> </DescriptionSet> <DescriptionSet lang="de"> <PluginName>Wechseldatenträger</PluginName> <Description>Plugin zum Unterdrücken des Standby wenn Wechseldatenträger angeschlossen sind</Description> <AuthorName>DecaTec</AuthorName> </DescriptionSet> </WsapmPlugin>
In stellt eine sog. DescriptionSet die Beschreibung eines Plugins für eine bestimmte Sprache dar. Die Sprache wird dabei mit dem Attribut lang angegeben und ist ein zweistelliger Sprachcode nach ISO 639-1 (z.B. „en“ für Englisch, „de“ für Deutsch). Der hier angegebene Name des Plugins, die Beschreibung und der Name des Autors werden in der entsprechenden Sprache des Benutzers auf der Oberfläche von WSAPM angezeigt.
Weitere Informationen zum Plugin
Darüber hinaus ist es auch möglich, weitere Informationen zu einem Plugin anzugeben (z.B. wenn zu dem Plugin weitere Erklärungen notwendig sind). Dazu wird eine Datei ReadMe.txt dem Plugin hinzugefügt. Die Inhalte dieser Datei werden angezeigt, wenn auf der Oberfläche auf die Schaltfläche Plugin Info geklickt wird (Tabe Plugins in den Einstellungen). Es können auch weitere Dateien für andere Sprachen hinzugefügt werden: hier sollte dann wieder ein zweistelliger Sprachcode an den Dateinamen angehängt werden (z.B. ReadMe_de.txt für eine Beschreibung des Plugins in Deutsch).
Diese Dateien sind dabei optional. Wenn ein Plugin keine ReadMe-Datei beinhaltet, werden beim Klick auf die Schaltfläche Plugin Info einfach nur allgemeine Informationen zu einem Plugin angezeigt.
Das Plugin für die Verteilung vorbereiten
Nachdem die Implementierung des Plugins damit abgeschlossen ist, kann das Plugin für die Verteilung vorbereitet werden. Dazu sollte die Solution zunächst einmal gebaut werden (im Release-Modus). Anschließend suchen wir den bin\Release Ordner im Projektverzeichnis. Dieser enthält die gebauten Dateien unseres Plugins. Wichtig ist in diesem Fall nur die Datei RemovableDevicesPlugin.dll. Die anderen Dateien (v.a. die Wsapm.Extensions.dll) sollte nicht weitergegeben werden.

Diese Datei wird nun durch ein ZIP-Programm (z.B. 7zip) gepackt. Wichtig dabei ist, dass es sich um eine ZIP-Datei (Dateiendung *.zip) handelt. Nur so kann das Plugin in WSAPM installiert werden. Diese ZIP-Datei kann nun weitergeben werden.
Installation des Plugins
Das Plugin lässt sich nun in den Einstellungen von WSAPM installieren. Dazu einfach in die Tabe Plugins wechseln und auf Plugin installieren klicken. WSAPM wird im Rahmen der Installation beendet und neu gestartet. Danach muss das Plugin nur noch in den Einstellungen aktiviert werden.

Weitere Möglichkeiten
Dieses einfache Plugin wurde von Grund auf entwickelt. Wer sich nicht mit der Erstellung des Plugin-Grundgerüsts beschäftigen will, für den gibt es ein Vorlage als Visual Studio Solution zum Download. Zu finden ist diese auf der Seite von Windows Server Advanced Power Management. Mit Hilfe dieser Vorlage ist im Grunde genommen nur noch die reine Plugin-Logik zu implementieren.
Darüber hinaus bietet es sich an, ein Plugin zu lokalisieren, wenn dieses nicht nur für den privaten Gebrauch programmiert wurde und weitergegeben werden soll. Windows Server Advanced Power Management unterstützt aktuell Deutsch und Englisch, daher wäre es wünschenswert, wenn Plugins ebenso beide Sprachen unterstützen würden.
Da die Lokalisierung von .NET Anwendungen den Rahmen dieses Artikels sprengen würde, wird an dieser Stelle nicht weiter auf dieses Thema eingegangen.
Sourcecode
Der gesamte Sourcecode des entwickelten Plugins kann hier herunter geladen werden. Es wurde lediglich die Lokalisierung (Deutsch/Englisch) für das entwickelte Plugin hinzugefügt.
Damit der Code als Plugin lauffähig ist, muss nur noch eine echte GUID in das WsapmPlugin Attribut eingefügt werden, wie bereits weiter oben beschrieben.
Der Sourcecode des Plugins ist hier zu finden:
Wsapm-RemovableDevices@Codeberg
Ihr habt ein eigenes Plugin entwickelt?
Falls ihr ein eigenes Plugin für WSAPM entwickelt habt und der Meinung seid, dass dieses Plugin auch für andere interessant sein könnte, dann schreibt mir doch einfach eine E-Mail. Beschreibt kurz, was euer Plugin macht und wie es funktioniert. Ich werde dann das Plugin (mir eurer Genehmigung) auf der Website veröffentlichen, so dass es auch andere herunterladen und nutzen können.
Falls ihr eine gute Idee für ein Plugin habt, es aber nicht selbst programmieren wollt, könnt ihr mir natürlich auch eine E-Mail schreiben.