Tutorial: Script-Command erstellen

Dieses Tutorial zeigt, wie ein PowerShell-Script als vollwertiger Command im Host registriert wird. Am Ende steht ein Add-in, das einen Script-Command deklariert, ein .ps1-Script ausführt und über das ##wvds-Protokoll mit dem Host kommuniziert — Fortschrittsanzeige, Benachrichtigungen und alles, was dazugehört.

Zurück zur Übersicht.

Voraussetzungen

  • PowerShell 7+ (pwsh.exe) im Systempfad
  • WvdS Host Shell (installiert und lauffähig)
  • Ein beliebiger Texteditor für .ps1- und .json-Dateien

Ein FPC-Compiler ist für Script-Commands nicht nötig — es wird keine DLL kompiliert.

Projektstruktur

csv-export/
├── plugin.json              ← Manifest
├── package.nls.json         ← Standard-Übersetzung
├── media/
│   └── export-csv.svg       ← Command-Icon
└── scripts/
    └── export-csv.ps1       ← PowerShell-Script

Im Unterschied zu nativen Add-ins gibt es keinen bin/-Ordner und keine DLL. Das gesamte Add-in besteht aus dem Manifest und dem Script.

Schritt 1: Manifest erstellen

Die Datei plugin.json deklariert den Script-Command. Das entscheidende Feld ist kind: „script“, das den Host anweist, kein DLL-Laden auszulösen, sondern das angegebene Script zu starten.

{
  "id": "wvds.csv-export",
  "name": "csv-export",
  "displayName": "%displayName%",
  "version": "36.01.25.001",
  "publisher": "wvds",
  "kind": "native",
  "engineVersion": "^1.0.0",
  "activationEvents": ["onCommand:csv-export.run"],
  "permissions": [],
  "contributes": {
    "commands": [
      {
        "command": "csv-export.run",
        "title": "%cmdRunTitle%",
        "category": "Export",
        "icon": "media/export-csv.svg",
        "kind": "script",
        "script": "scripts/export-csv.ps1"
      }
    ],
    "keybindings": [
      {
        "command": "csv-export.run",
        "key": "Ctrl+Shift+E",
        "when": ""
      }
    ]
  }
}

Die Felder kind und script im Command-Block sind der einzige Unterschied zu einem nativen Command. Alles andere — title, category, icon, keybindings — funktioniert identisch.

Die NLS-Datei package.nls.json:

{
  "displayName": "CSV-Export",
  "cmdRunTitle": "CSV-Export ausführen"
}

Schritt 2: PowerShell-Script schreiben

Das Script scripts/export-csv.ps1 ist ein gewöhnliches PowerShell-Script. Es kann das WvdSHostContract-Modul importieren, um strukturiert mit dem Host zu kommunizieren.

# WvdS Host-Contract importieren
Import-Module "$PSScriptRoot\..\scripts\WvdSHostContract.psm1"

# Fortschritt melden
Write-HostStatus -Text "CSV-Export gestartet"
Write-HostProgress -Percent 0

# Beispiel: Daten verarbeiten
$items = @("Eintrag A", "Eintrag B", "Eintrag C", "Eintrag D", "Eintrag E")
$total = $items.Count
$output = @()

for ($i = 0; $i -lt $total; $i++) {
    $output += $items[$i]
    $pct = [math]::Floor((($i + 1) / $total) * 100)
    Write-HostProgress -Percent $pct
    Write-Output "Verarbeite: $($items[$i])"
    Start-Sleep -Milliseconds 500
}

# Ergebnis speichern
$outputPath = "$env:TEMP\export.csv"
$output | Out-File -FilePath $outputPath -Encoding UTF8

# Host benachrichtigen
Write-HostProgress -Percent 100
Write-HostNotification -Message "CSV-Export abgeschlossen: $outputPath"

Drei Dinge passieren hier:

  • Write-HostProgress aktualisiert die Fortschrittsanzeige in der StatusBar.
  • Write-Output erzeugt reguläre Textausgabe, die im PowerShell-Panel erscheint.
  • Write-HostNotification zeigt am Ende eine Toast-Benachrichtigung.

Schritt 3: Paket schnüren

Das Add-in wird als .wvdsx-Datei (ZIP) verpackt. Die Struktur innerhalb des Archivs entspricht der Projektstruktur:

csv-export.wvdsx (ZIP)
├── plugin.json
├── package.nls.json
├── media/
│   └── export-csv.svg
└── scripts/
    └── export-csv.ps1

Installation über die CLI:

WDocHost.exe --install-extension csv-export.wvdsx

Schritt 4: Testen

Nach der Installation erscheint der Command Export: CSV-Export ausführen in der CommandPalette. Der Benutzer kann ihn dort aufrufen oder Ctrl+Shift+E drücken.

Beim ersten Aufruf zeigt der Host einen Bestätigungsdialog mit dem Pfad zum Script. Nach Bestätigung:

  1. Das BottomPanel öffnet sich automatisch und wechselt zum PowerShell-Pane.
  2. Ein neuer Tab CSV-Export ausführen erscheint mit dem ▶-Badge (laufend).
  3. Die Textausgabe (Verarbeite: …) strömt in Echtzeit in den Tab.
  4. Die StatusBar zeigt den Fortschrittsbalken.
  5. Nach Abschluss wechselt der Tab-Badge zu ✓ und die Benachrichtigung erscheint.

Was unter der Haube passiert

Der Host-interne Ablauf bei einem Script-Command ist kürzer als bei einem nativen Command:

  1. Der Host findet den Command csv-export.run in der Registry.
  2. Der TScriptCommandProxy delegiert an den TShellScriptHost.
  3. Der ScriptHost prüft die Genehmigungsliste (Erst-Ausführung → Dialog).
  4. Der ScriptHost startet pwsh.exe -NoProfile -NonInteractive -File scripts/export-csv.ps1.
  5. Ein TScriptReaderThread liest stdout zeilenweise.
  6. Zeilen mit ##wvds[…]-Prefix werden erkannt, JSON-Payload geparst und an die Shell dispatcht (Synchronize für Thread-Sicherheit).
  7. Normaler Text geht direkt ins TWvdSScriptPanel.
  8. Bei Prozess-Ende wertet der Host den Exit-Code aus und aktualisiert den Tab-Status.

Es gibt keine DLL, keinen ABI-Handshake und keine Aktivierungsphase. Das Script läuft als eigenständiger Betriebssystem-Prozess.

Erweiterte Szenarien

Host-Command aus dem Script aufrufen

Ein Script kann registrierte Commands im Host auslösen:

Invoke-HostCommand -CommandId "assets.refresh"

Dafür muss das Manifest die Berechtigung host.commands enthalten:

"permissions": ["host.commands"]

Dokument im Host öffnen

Open-HostDocument -Path "C:\Daten\report.pdf"

Erfordert fs.read in den Manifest-Berechtigungen.

Weiter zur ScriptHost-Referenz oder zurück zur Übersicht.

Zuletzt geändert: den 15.03.2026 um 18:23