Inhaltsverzeichnis
ScriptHost & Host-Contract
Der ScriptHost ermöglicht es, PowerShell-Scripts als vollwertige Commands im Host auszuführen. Ein Script-Command wird im Manifest als kind: „script“ deklariert und verweist auf eine .ps1-Datei im Add-in-Paket. Der Host startet das Script als pwsh-Kindprozess, liest dessen Ausgabe asynchron über eine Pipe und stellt sie im PowerShell-Panel des BottomPanels dar.
Ziel dieser Architektur ist es, leichtgewichtige Automatisierungen ohne DLL-Kompilierung und ohne ABI-Handshake zu ermöglichen. Im Unterschied zu nativen Commands, die den vollständigen Aktivierungszyklus (DLL laden, CreatePlugin, Activate) durchlaufen, startet ein Script-Command sofort als Betriebssystem-Prozess. Der Vorteil besteht darin, dass PowerShell-Scripts die gesamte Windows-Infrastruktur nutzen können — Dateisystem, Registry, REST-APIs, COM-Objekte — während sie trotzdem über ein strukturiertes Protokoll mit dem Host kommunizieren.
Zurück zur SDK-Übersicht oder zur Hauptübersicht.
Prozess-Lifecycle
Wenn der Benutzer einen Script-Command auslöst, durchläuft der ScriptHost folgende Schritte:
- Sicherheitsprüfung: Bei der ersten Ausführung eines Scripts zeigt der Host einen Bestätigungsdialog mit dem vollständigen Pfad. Einmal genehmigte Scripts werden intern gespeichert und bei künftigen Aufrufen ohne Dialog gestartet.
- Prozess-Start: Der Host startet
pwsh.exe -NoProfile -NonInteractive -File <pfad>als Kindprozess mit gepipeterstdout/stderr-Umleitung. - Asynchrones Lesen: Ein Hintergrund-Thread liest
stdoutzeilenweise. Zeilen mit dem##wvds[…]-Prefix werden als Host-Nachrichten erkannt und an die Shell dispatcht. Normaler Text geht direkt ins PowerShell-Panel. - Abschluss: Der Host wertet den Exit-Code aus — 0 = Erfolg, 1 = Fehler, 2 = Abbruch — und aktualisiert den Tab-Status im PowerShell-Panel.
- Abbruch: Der Benutzer kann ein laufendes Script über den Stop-Button im PowerShell-Panel abbrechen. Der Host sendet
TerminateProcessan denpwsh-Prozess.
Jeder Script-Lauf erscheint als eigener Tab im PowerShell-Panel des BottomPanels. Mehrere Scripts können parallel laufen. Das BottomPanel wird automatisch sichtbar, wenn ein Script startet.
##wvds-Protokoll
Die Kommunikation zwischen Script und Host läuft über stdout. Der Host erkennt strukturierte Nachrichten an einem Prefix:
##wvds[typ payload]
- typ — ein Schlüsselwort, das die Nachrichtenart bestimmt.
- payload — ein JSON-String mit den Nachrichtendaten.
Normaler Text (ohne ##wvds-Prefix) wird als reguläre Script-Ausgabe im PowerShell-Panel dargestellt.
Nachrichtentypen
| Typ | Payload | Host-Aktion |
progress | {„percent“: 67} | Aktualisiert die StatusBar-Fortschrittsanzeige. |
status | {„text“: „Verarbeite Datei 3/10“} | Setzt temporär ein StatusBar-Item. |
notify | {„message“: „Export abgeschlossen“} | Zeigt eine Benachrichtigung im NotificationStack. |
open | {„path“: „C:\\Daten\\report.pdf“} | Öffnet ein Dokument in den DocumentTabs. |
command | {„id“: „assets.refresh“} | Löst einen registrierten Command im Host aus. |
Beispiel
Ein Script, das eine CSV-Datei exportiert und den Fortschritt an den Host meldet:
Write-Output '##wvds[status {"text":"CSV-Export gestartet"}]'
Write-Output '##wvds[progress {"percent":0}]'
$rows = Get-Content -Path $InputFile
$total = $rows.Count
for ($i = 0; $i -lt $total; $i++) {
# ... Verarbeitung ...
$pct = [math]::Floor(($i / $total) * 100)
Write-Output "##wvds[progress {`"percent`":$pct}]"
}
Write-Output '##wvds[progress {"percent":100}]'
Write-Output '##wvds[notify {"message":"CSV-Export abgeschlossen"}]'
WvdSHostContract-Modul
Damit Scripts nicht manuell ##wvds[…]-Strings zusammenbauen müssen, liefert der Host das PowerShell-Modul WvdSHostContract mit. Es stellt fünf Cmdlets bereit, die das Protokoll kapseln.
Installation
Das Modul liegt im Installationsverzeichnis der Shell unter scripts/WvdSHostContract.psm1. Scripts importieren es explizit:
Import-Module "$PSScriptRoot\..\scripts\WvdSHostContract.psm1"
Cmdlets
Write-HostProgress
Write-HostProgress -Percent 67
Sendet ##wvds[progress {„percent“:67}]. Aktualisiert die Fortschrittsanzeige in der StatusBar und im PowerShell-Panel.
Write-HostStatus
Write-HostStatus -Text "Verarbeite Datei 3/10"
Sendet ##wvds[status {„text“:„Verarbeite Datei 3/10“}]. Setzt temporär ein StatusBar-Item mit dem angegebenen Text.
Write-HostNotification
Write-HostNotification -Message "Export abgeschlossen"
Sendet ##wvds[notify {„message“:„Export abgeschlossen“}]. Zeigt eine Toast-Benachrichtigung im NotificationStack der Shell.
Open-HostDocument
Open-HostDocument -Path "C:\Daten\report.pdf"
Sendet ##wvds[open {„path“:„C:\\Daten\\report.pdf“}]. Öffnet das angegebene Dokument in den DocumentTabs.
Invoke-HostCommand
Invoke-HostCommand -CommandId "assets.refresh"
Sendet ##wvds[command {„id“:„assets.refresh“}]. Löst einen registrierten Command im Host aus. Der Command muss in den Berechtigungen des Add-ins unter host.commands gelistet sein.
Sicherheit
Script-Commands unterliegen dem Berechtigungsmodell des Hosts. Folgende Prüfungen gelten:
- Erst-Ausführung: Jedes Script muss vom Benutzer einmalig genehmigt werden. Der Bestätigungsdialog zeigt den vollständigen Pfad zur
.ps1-Datei. - Invoke-HostCommand: Das Script darf nur Commands aufrufen, die im
permissions-Array des Manifests unterhost.commandsgelistet sind. Nicht autorisierte Aufrufe erzeugen einen Fehler im PowerShell-Panel. - Open-HostDocument: Erfordert
fs.readin den Manifest-Berechtigungen. - Kein Sandbox-Versprechen: Wie bei nativen Add-ins gilt: PowerShell-Scripts laufen mit den Rechten des Host-Prozesses. Das Berechtigungsmodell ist kooperativ, nicht erzwungen.
PowerShell-Panel
Das PowerShell-Panel ist ein Pane im BottomPanel der Shell, das über Ctrl+J erreichbar ist. Es zeigt die Ausgabe laufender und abgeschlossener Script-Läufe in einer tabulierten Ansicht.
- Tab pro Script-Lauf: Jedes gestartete Script erhält einen eigenen Tab mit Titel und Status-Badge (▶ laufend, ✓ abgeschlossen, ✗ fehlgeschlagen, ■ abgebrochen).
- Monospace-Textanzeige: Ausgabezeilen werden in Consolas 9pt gerendert.
stderr-Zeilen erscheinen in der Fehler-Farbe des aktiven Themes. - Ring-Buffer: Pro Tab werden maximal 5.000 Zeilen gespeichert. Ältere Zeilen fallen automatisch heraus.
- Auto-Scroll: Neue Ausgaben scrollen den Tab automatisch nach unten, es sei denn, der Benutzer hat manuell nach oben gescrollt.
Weiter zum Script-Command Tutorial oder zurück zur SDK-Übersicht.