====== ScriptHost & Host-Contract ====== Der ScriptHost ermöglicht es, PowerShell-Scripts als vollwertige [[..:contributions:commands|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 [[start|SDK-Übersicht]] oder zur [[..:start|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 '' als Kindprozess mit gepipeter ''stdout''/''stderr''-Umleitung. - **Asynchrones Lesen:** Ein Hintergrund-Thread liest ''stdout'' zeilenweise. 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 ''TerminateProcess'' an den ''pwsh''-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 [[..:sicherheit|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 unter ''host.commands'' gelistet sind. Nicht autorisierte Aufrufe erzeugen einen Fehler im PowerShell-Panel. * **Open-HostDocument:** Erfordert ''fs.read'' in 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 [[..:tutorials:script-command|Script-Command Tutorial]] oder zurück zur [[start|SDK-Übersicht]].