Windows-Anwendungen mit PowerShell und Windows Presentation Framework (WPF) – Teil 1

Die PowerShell bietet uns vielfältige Möglichkeiten bei der Automatisierung von Abläufen unter Windows. Im PowerShell-Kommandozeilen-Fenster lassen sich einfache Befehle oder komplexe Skripte ausführen. Doch als Nachteil der PowerShell sehen viele, dass es keine Möglichkeit gibt eigene Oberflächen zu gestalten. Deshalb geben sie die Ausgabewerte einfach in dem PowerShell-Kommandozeilen-Fenster aus. Das wird jedoch schnell unübersichtlich und ist für eine weitere Verarbeitung kaum geeignet.

clip_image001

Mit dieser Artikelserie möchte ich Ihnen die Vorgehensweise zur Erstellung von ansprechenden Windows-Anwendungen mit PowerShell und WPF aufzeigen.

Artikel der Serie

    • Teil 1: Einleitung/Grundlagen(dieser Beitrag)
    • Teil 2: Anwendungsmenüs und Steuerelemente
    • Teil 3: Dynamisches Erstellen von Steuerelementen
    • Teil 4: Ausführen von SQL-(oder anderen) Skripten
    • …weitere Beiträge in Vorbereitung

Die Artikelserie wendet sich an alle die Interesse an dem Thema PowerShell und damit bereits ein wenig experimentiert haben. Da ich jeden Schritt in der Anleitung erklären werde, sollte Sie dies schnell und einfach auf Ihre eigene Aufgabenstellung adaptieren können.

Vorbetrachtungen

Seit einiger Zeit beschäftige ich mich der Einbindung des Windows Presentation Frameworks (WPF) in PowerShell-Skripte. Doch für was steht dieses WPF:

„Für Microsoft steht die Windows Presentation Framework (WPF) als Zukunft der Rich-Client-Anwendungen. Sie wurde von Grund auf neu entwickelt, um eine möglichst saubere und klar strukturierte Grundlage für Anwendungen zu bieten. Windows Forms wird dagegen nicht mehr weiterentwickelt und bleibt damit auf dem heutigen Stand des .NET-Frameworks 2.0 stehen. Als Entwickler von Windows-Forms-Anwendungen sollte man sich daher rechtzeitig Gedanken machen und sich mit der neuen Technik beschäftigen.“ (Quelle:WPF 4.5 und XAML: Grafische Benutzeroberflächen für Windows inkl. Entwicklung von Windows Store Apps, Dr. Holger Schwichtenberg, Jörg Wegener)

Nachdem ich mit PowerShell und WPF einiges an Wissen und Erfahrung aufgebaut habe, möchte ich Ihnen dieses in einer Serie von Blog-Einträgen als eine Schritt-für-Schritt-Anleitung mit Hintergrundinformationen liefern. Das Ziel besteht darin, dass Sie selbst in der Lage sind, mit nur wenigen Zeilen Sourcecode ansprechende Oberflächen zu gestalten.

Aufgabenstellung

Damit die von mir zu erstellende Anwendung auch eine sinnvolle Aufgabenstellung zugrunde liegt, habe ich mich entschlossen eine Oberfläche zu gestalten, mit der Sie SQL Server-Skripte ausführen und die Ergebnisse in interaktiven Tabellen darstellen können. Die Anwendung soll über eine Menüleiste verfügen, mit der Sie verschiedene Funktionen ausführen können.

Einen Screenshot der in dieser Artikelserie zu erstellenden Anwendung sehen Sie im folgenden Bild:

image

In dem Anwendungsfenster werden die einzelnen SQL-Befehle einer geöffneten SQL-Datei dargestellt und die Ergebnisse in Tabellenform dargestellt.

Den vollständigen Sourcecode für die Anwendung stelle ich Ihnen im letzten Artikel dieser Serien zur Verfügung. Das verwendete TSQL-Skript soll nur als Beispiel fungieren, um Ihnen die Verwendung in dem Programm zu verdeutlichen. Sie können auch jedes andere TSQL-Skript verwenden, das über mindestens eine Ausgabe verfügt.

Möglichkeiten der Ausgabe von Daten in der PowerShell

PowerShell bieten außer der Ausgabe der Daten am Bildschirm die Möglichkeit diese in verschiedenen Dateiformaten auszugeben. Dazu stehen Ihnen entsprechende Cmdlets zur Verfügung bspw. Out-File oder Export-CSV. Außerdem können Sie Cmdlets verwenden, um die Ausgabe in ein bestimmtes Format zu erzwingen wie z. B. ConvertTo-HTML, ConvertTo-JSON.

Das folgende Beispiel zeigt Ihnen die Verwendung von ConvertTo-HTML in Verbindung von Out-File. Dabei werden die Eigenschaften der aktiven Prozesse in eine HTML-Datei konvertiert und anschließend in eine Textdatei exportiert. Diese wird im nächsten Schritt (Invoke-Item) mit dem Browser geöffnet:

Get-Process | ConvertTo-Html | Out-File "C:\TEMP\Test.html"; Invoke-Item "C:\TEMP\Test.html"

clip_image003

Seit PowerShell 2.0 wurde das CmdLet Out-GridView eingeführt und mit PowerShell 3.0 erweitert. Damit haben Sie sehr einfach und schnell die Möglichkeit Ergebnisse eines Befehls grafisch ansprechend darzustellen. Außerdem können Sie damit bereits einfache Operationen zur Sortierung und Selektion durchführen. Die Verwendung des CmdLets ist sehr einfach, da Sie die Ergebnisse eines anderen CmdLets oder Scripts einfach durch einen Pipe-Operator zur Ausgabe an das Out-GridView CmdLet übergeben können. Hier ein Beispiel:

Get-Process | Out-GridView

image

Diese Lösungen stoßen schnell an Grenzen, wenn es darum geht Interaktion wie z. B. Menüs, Sortierung  oder weitere Ausgaben mit zu integrieren. Außerdem bedarf es einiger Nacharbeit um die Formatierung der Ausgaben gut lesbar zu gestalten.

Eine andere Lösung ist die Erstellung eines Windows Forms unter Verwendung der entsprechenden .NET-Library.

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$frm = New-Object System.Windows.Forms.Form
$frm.Text = "Test-Formular"
[void] $frm.ShowDialog()

clip_image004

Damit lassen sich ansprechende Windows-Oberflächen gestalten. Jedoch ist das Design solcher Oberflächen aufwendig, da keine unterstützenden Tools zur Verfügung stehen. Beispiele für solche Anwendungen finden Sie z. B. in der MSDN (http://msdn.microsoft.com/en-us/library/ff730941.aspx) oder auf Codeplex (http://pshyperv.codeplex.com/). Wie man an diesen Beispielen sehen kann, ist eine ganze Menge Sourcecode notwendig, bevor man eine einigermaßen ansprechende Anwendung bekommt.

Zur Vereinfachung der Arbeit mit den Windows Formularen gibt es ein Projekt auf Codeplex ShowUI. Die Bibliotheken in diesem Projekt stellen Ihnen Windows Forms Controls für die Einbindung in die PowerShell zur Verfügung.

Die Oberfläche

Doch nun genug der Vorrede! Gehen wir in medias res und bauen im ersten Schritt eine einfache WPF-Anwendung bestehend aus einem Fenster. Für die WPF-Anwendung benötigen Sie eine eXtensible Application Markup Language (XAML)-Definition. Die XAML-Definition hat eine XML-Struktur. Sie können eine solche Struktur direkt in das PowerShell-Skript einbinden (als String) oder aus einer anderen Datei (Erweiterung *.xaml) laden. Für unser Beispiel binde ich der Einfachheit halber die XAML-Definition direkt in das Skript als mehrzeilige Zeichenkette ein. Durch die vorgesetzte Typdeklaration [xml] wird die Zeichenkette in eine XML-Struktur konvertiert.

Die Definition eines Windows-Fensters in einer XAML-Struktur für die Erstellung einer Windows-Anwendung besteht aus einem Windows-Tag und der Einbindung der zwei zusätzlichen Namensräume:

  • http://schemas.Microsoft.com/winfx/2006/xaml/presentation ist der Kern-WPF-Namespace. Es umfasst alle WPF-Klassen, einschließlich der Steuerelemente, die Sie zum Erstellen von Benutzeroberflächen verwenden. In diesem Beispiel ist der Namespace ohne ein Namespacepräfix deklariert, so wird er der Standard-Namespace für das gesamte Dokument. Mit anderen Worten, jedes Element wird automatisch in diesem Namespace platziert, sofern Sie nichts anderes angeben.
  • http://schemas.microsoft.com/winfx/2006/xaml ist der XAML-Namespace. Es enthält verschiedene XAML-Dienstprogramm-Funktionen, die beeinflussen, wie die Anwendungsoberfläche interpretiert wird. Diesem Namespace ist das Präfix X zugeordnet. Das bedeutet, Sie können es anwenden, indem man das Namespace-Präfix vor dem Namen des Elements (wie in <x:ElementName>) setzt.

Um den ersten Schritt übersichtlich und leicht verständlich zu halten, habe ich nur den Titel dem Fenster zugewiesen. Auf weitere Anpassung von Eigenschaften oder zusätzliche Steuerelemente habe ich verzichtet.

Im nächsten Schritt muss das Assembly für das Presentation Framework zugewiesen werden. Diese Zuweisung ist nur dann erforderlich, wenn Sie das Skript im PowerShell-Kommandozeilen-Fenster ausführen wollen. Bei der Verwendung in der integrierten PowerShell Skript Umgebung (PowerShell ISE) ist dies nicht erforderlich, da diese bereits das Assembly enthält. Trotzdem empfehle ich Ihnen das Assembly immer einzubinden, da Sie nicht wissen, ob das Programm von der PowerShell-ISE oder vom PowerShell-Kommandozeilen-Fenster gestartet wird.

Danach erstellen Sie ein Objekt vom Typ XMLNodeReader und weisen diesem die XML-Struktur zu. Das ist die Voraussetzung, das Objekt im XAMLReader zu laden. Nachdem das Objekt geladen ist, steht Ihnen die Methode ShowDialog zum Anzeigen des Windows-Fensters zur Verfügung.

[xml]$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml&quot;
        Title="Test-Anwendung">
</Window>
"@
Add-Type -Assembly PresentationFramework
$Form=[Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $xaml))
[void]$Form.ShowDialog()

Damit ist Ihre erste PowerShell-WPF-Anwendung fertig und Sie können Sie ausführen – entweder mit der PowerShell-IDE oder mit der PowerShell-Kommandozeile (wie auf dem folgenden Bild zu sehen).

image

Hinweis: Wenn Sie die PowerShell 2.0 von der Kommandozeile aus verwenden, wird beim Ausführen dieses Skripts ein Fehler angezeigt:

Load : Ausnahme beim Aufrufen von "Load" mit 1 Argument(en):  "Die in der Assembly "PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" definierte Instanz von "Window" kann nicht erstellt werden. Bei
m aufrufenden Thread muss es sich um einen STA-Thread handeln, da dies für viele Komponenten der Benutzeroberfläche erforderlich ist."

Die Ursache dieses Fehlers liegt darin, dass PowerShell in der Version 2.0 noch kein Single Threaded Application unterstützt. Das Problem können Sie lösen, wenn Sie die PowerShell mit der Option STA aufrufen:

PowerShell.exe –STA

Dieses Problem tritt in der PowerShell ISE bzw. bei neueren PowerShell-Versionen nicht mehr auf.

Hinweis: Beim Anzeigen des Windows-Fensters wird die Methode ShowDialog verwendet. Diese Methode stellt einen blockierenden Aufruf des Fensters dar und stoppt die Verarbeitung des PowerShell-Skripts. Dies bedeutet, das alle Befehle im PowerShell-Skript nach dem Aufruf ShowDialog erst ausgeführt werden, wenn das Fenster wieder geschlossen wurde. Aktionen innerhalb des Fensters können somit nur über Ereignisse (Events) angetriggert werden. Dazu kommen wir in einem späteren Artikel dieser Serie.
XAML-Editoren

Für jemanden, der keine oder nur wenig Erfahrung mit der Definition und der Struktur von XAML hat, bietet es sich an, einen Editor zum Bearbeiten zu verwenden. Ich habe mich für Visual Studio entschieden (bereits ab der Express Edition verfügbar). Neben Visual Studio als Bearbeitungsprogramm von XAML-Dateien bietet Microsoft noch Microsoft Expression Blend an.

Neben den Tools von Microsoft gibt es aber noch eine Reihe anderer Editoren zum Bearbeiten von XAML-Strukturen – teilweise kostenfrei. Eine kurze Übersicht finden Sie unter http://codeflow49.blogspot.de/2010/03/four-free-xaml-editors-reviewed.html.

Da ich für die Erstellung der dieser Blogserie zugrundeliegenden Artikel Visual Studio 2013 verwendet habe, möchte ich Ihnen eine kurze Einführung zur Bearbeitung der XAML-Dateien liefern.

Für XAML-Datei gibt es in Visual Studio keinen eigenen Projekttyp. Auch das Öffnen einer Datei mit der Erweiterung XAML bietet nicht die Möglichkeit der grafischen Bearbeitung der Oberfläche. Ein Workaround ist Projekt auf Basis einer WPF Applikation anzulegen.

image

Dieses Projekt beinhaltet zwar eine Menge von Dateien, die Sie nicht benötigen, doch ich habe bisher keinen besseren Weg zum Bearbeiten von XAML-Dateien gefunden.

In der durch diese Projektvorlage erstellten Struktur benötigen Sie ausschließlich die MainWindow.xaml-Datei zum Bearbeiten der XAML-Definition. Wenn Sie diese Datei öffnen, erhalten Sie im Hauptbereich eine grafische und Code-Ansicht. In der grafischen Ansicht können Sie nun über die Toolbox Steuerelemente einfügen und über die Eigenschaften Formatierungen anpassen. Änderungen sind aber auch direkt in der Code-Ansicht möglich und werden dann sofort in die grafische Ansicht übernommen.

image

Nachdem Sie das MainWindow entsprechend Ihren Vorstellungen gestaltet haben, brauchen Sie nur die XAML-Struktur in die Zeichenkette im PowerShell-Skript zu kopieren.

Einige Beispiele in für WPF Anwendungen hat Microsoft gesammelt und auf WPF Documentation Samples – Release: Deutsche WPF-Dokumentation-Beispiele veröffentlicht. Hier können Sie ein wenig stöbern und verschiedene WPF Anwendungen direkt testen.

Fazit

Mit dem ersten Teil dieser Serie wollte ich Ihnen neben vielen Hintergrundinformationen zeigen, wie einfach Sie mit der PowerShell eine Windows-Anwendung erzeugen können. Nun können Sie damit ein wenig experimentieren. Sollten Sie Fragen haben, können Sie mich gerne per Mail kontaktieren. Ansonsten würde ich mich freuen, Sie beim zweiten Teil dieser Serie wenn es darum geht Steuerelemente und ein Menü in diese Windows-Anwendung zu integrieren, wieder als Leser begrüßen zu dürfen.

Nach diesem Blogeintrag werden Sie sich vielleicht fragen, warum man PowerShell für solche Aufgaben verwenden sollte. Dazu habe ich einen interessanten Artikel in der MSDN Magazin gefunden, den ich auszugsweise hier einfügen möchte:

“…PowerShell unterscheidet sich in vielerlei Weise von anderen Programmiertechnologien: Schwerpunkt auf aufgabenorientierten Abstraktionen auf hoher Ebene, das adaptive Typsystem, mit dem unterschiedliche Typsysteme (.NET, Windows Management Instrumentation [WMI], XML, ADSI, ADO usw.) normalisiert werden und das Ihnen das Hinzufügen von Elementen zu Typen und Instanzen ermöglicht, das Datenflussmodul, mit dem ein Großteil des API-Impedance Mismatch-Codes überflüssig wird, den Entwickler schreiben müssen, sowie die Unterstützung für das Adhoc-Entwicklungsmodell.

Das Adhoc-Modell ist der Ausgangspunkt zur Lösung eines Problems mithilfe informeller Verfahren. Wenn Sie sich dafür entscheiden, es häufiger zu verwenden, können Sie es in ein informelles Skript konvertieren, und wenn Sie es freigeben möchten, können Sie es formeller gestalten. Als Ersteller von Tools fertigen wir häufig Tools für Benutzer mit unterschiedlichen Fähigkeiten an, sodass es wichtig ist, die Anforderungen und Erwartungen der gesamten Zielgruppe zu erfüllen. Meist ist dies mit der Bereitstellung einer GUI verbunden.”

“…Das Adhoc-Entwicklungsmodell basiert auf der PowerShell-Zielsetzung, gleichzeitig eine hervorragende interaktive Shell und eine Skriptsprache zu bieten. Bruce Payette, einer der Sprachdesigner, hat einmal gesagt, dass die Lebensdauer von 99 Prozent von PowerShell-Skripten mit der Befehlseingabe beginnt und mit dem Wagenrücklaufzeichen endet. PowerShell unterstützt einen großen Bereich von Skriptstilen, von interaktiven Einzeilern an einer Eingabeaufforderung über Funktionen im Bash-Stil, die "$args" verwenden, bis hin zu formelleren Skripts, bei denen Parameter benannt, typisiert und mit Validierung, Datenbindung und Hilfeattributen versehen sind. Der Grund für die Wahl dieses Ansatzes beruht auf meinen vielen Jahren als Unix-Entwickler, in denen ich riesige Mengen von Shellskripts geschrieben habe. Als meine Skripts dann von Benutzern verwendet wurden und diese mehr Funktionen forderten, habe ich die Skripts verworfen und in Tcl oder Perl neu geschrieben. Häufig ist es dann passiert, dass ich auch diese neuen Skripts verworfen und alles in C noch einmal neu geschrieben habe. Mir wurde klar, dass – auch wenn unterschiedliche Probleme einen unterschiedlichen Grad an Formalismus und Leistung erfordern – es Wahnsinn war, dass es kein einzelnes Tool gab, mit dem ich diesen großen Bereich von Skripterstellungsanforderungen abdecken konnte. Benutzer könnten ihre Lernarbeit dann investieren, um zu einem Experten für dieses Tool zu werden, anstatt über gute Kenntnisse in vielen verschiedenen Tools verfügen zu müssen. Es hat eine Weile gedauert, aber ich habe dann ein Tool erstellt, das genau diese Anforderung erfüllt. Ich hoffe, Sie haben Spaß an der Verwendung von PowerShell.”

Quelle: Jeffrey Snover, Distinguished Engineer und Lead Architect für Windows Server, Initiator von PowerShell

Advertisements
Über

Die IT-Welt wird immer komplexer und zwischen den einzelnen Komponenten gibt es immer mehr Abhängigkeiten. Nachdem ich durch meine tägliche Arbeit immer wieder vor der Herausforderung stehe, komplexe Probleme zu lösen, möchte ich diese Seite dafür verwenden, Euch den einen oder anderen Tipp zu geben, wenn Ihr vor ähnlichen Aufgabenstellungen steht.

Veröffentlicht in Allgemein

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: