SwyxTray und Firefox-Plugin in das Repository aufnehmen

Windows-Tray-Anwendung (CLMgr-Anbindung an SwyxIt!) samt WebSocket-Zugang,
Firefox-Erweiterung und Browser-Beispielclient.
This commit is contained in:
2026-08-21 11:33:52 +02:00
commit 78b17a1350
28 changed files with 4396 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
{
// Die App hat kein Fenster: sichtbar ist nur das Symbol im Infobereich der
// Taskleiste, alles Weitere steht im Protokoll unter
// %LOCALAPPDATA%\SwyxTray\swyxtray.log.
"version": "0.2.0",
"configurations": [
{
// Der Standardweg — funktioniert auch, wenn VS Code remote verbunden
// ist: eine geplante Aufgabe startet die App in der Desktop-Sitzung des
// angemeldeten Benutzers (nur dort gibt es eine Taskleiste fuer das
// Symbol), danach haengt sich der Debugger an den Prozess.
"name": "SwyxTray debuggen (Desktop-Sitzung)",
"type": "coreclr",
"request": "attach",
"preLaunchTask": "SwyxTray im Desktop starten (Debug)",
"processName": "SwyxTray.exe"
},
{
// Direkter Start durch den Debugger. Bei lokal laufendem VS Code
// gleichwertig; bei Remote-Verbindung landet der Prozess in der
// Sitzung des VS-Code-Servers — die App laeuft dann, aber ohne
// sichtbares Tray-Symbol (dort existiert keine Taskleiste).
"name": "SwyxTray starten (direkt, ohne Tray bei Remote)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build (Debug)",
"program": "${workspaceFolder}/src/SwyxTray/bin/x64/Debug/net10.0-windows/win-x64/SwyxTray.exe",
"args": ["--verbose"],
"cwd": "${workspaceFolder}/src/SwyxTray",
"console": "internalConsole",
"stopAtEntry": false
},
{
// Fuer eine bereits laufende Instanz, etwa aus dem Autostart.
"name": "An laufende SwyxTray anhaengen",
"type": "coreclr",
"request": "attach",
"processName": "SwyxTray.exe"
}
]
}
+67
View File
@@ -0,0 +1,67 @@
# Startet SwyxTray in der Desktop-Sitzung des angemeldeten Benutzers.
#
# Hintergrund: Laeuft VS Code remote (SSH, Tunnel), startet dessen Debugger
# Prozesse in der Sitzung des VS-Code-Servers - meist Sitzung 0, und dort gibt
# es keine Taskleiste, also auch kein Tray-Symbol. Eine geplante Aufgabe ohne
# /RU laeuft dagegen mit dem interaktiven Token des Benutzers und landet damit
# auf dem Desktop. Braucht keine Administratorrechte.
#
# Wird von der Aufgabe "SwyxTray im Desktop starten (Debug)" aufgerufen; die
# Einzelinstanz-Sperre und der Build sind dann schon erledigt (dependsOn).
#
# Bewusst KEIN $ErrorActionPreference = 'Stop': Die Aufgabe leitet stderr um,
# und in Windows PowerShell 5.1 wird dann jede stderr-Zeile eines nativen
# Programms zu einem ErrorRecord - mit 'Stop' bricht das Skript an der Stelle
# mit einer irrefuehrenden Meldung ab. Stattdessen wird nach jedem
# schtasks-Aufruf $LASTEXITCODE geprueft.
param(
[Parameter(Mandatory = $true)][string]$Exe
)
$taskName = 'SwyxTray.F5'
if (-not (Test-Path $Exe)) {
Write-Host "FEHLER: Nicht gefunden: $Exe - erst bauen."
exit 1
}
# Ein soeben beendeter Prozess ist in Get-Process noch kurz als Leiche
# sichtbar. Damit die Warteschleife nicht darauf hereinfaellt, zaehlt nur ein
# PID, der vorher nicht da war.
$before = @(Get-Process SwyxTray -ErrorAction SilentlyContinue | ForEach-Object Id)
# /ST ist bei /SC ONCE Pflicht, der Zeitpunkt ist aber ohne Belang:
# gestartet wird sofort per /Run, danach wird die Aufgabe wieder entfernt.
$created = schtasks /Create /F /TN $taskName /TR "`"$Exe`" --verbose" /SC ONCE /ST 23:59 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Host "FEHLER: Geplante Aufgabe konnte nicht angelegt werden: $created"
exit 1
}
$run = schtasks /Run /TN $taskName 2>&1
if ($LASTEXITCODE -ne 0) {
schtasks /Delete /F /TN $taskName 2>&1 | Out-Null
Write-Host "FEHLER: Geplante Aufgabe konnte nicht gestartet werden: $run"
exit 1
}
# Die Aufgabe darf erst weg, wenn sie die EXE gestartet hat - /Run ist
# asynchron, ein zu fruehes /Delete wuerde den Start abwuergen.
$process = $null
foreach ($i in 1..60) {
$process = Get-Process SwyxTray -ErrorAction SilentlyContinue |
Where-Object { $before -notcontains $_.Id -and -not $_.HasExited } |
Select-Object -First 1
if ($process) { break }
Start-Sleep -Milliseconds 250
}
schtasks /Delete /F /TN $taskName 2>&1 | Out-Null
if (-not $process) {
Write-Host "FEHLER: SwyxTray ist nicht gestartet - Protokoll unter %LOCALAPPDATA%\SwyxTray pruefen."
exit 1
}
Write-Host "SwyxTray laeuft (PID $($process.Id), Sitzung $($process.SessionId))."
exit 0
+77
View File
@@ -0,0 +1,77 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build (Debug)",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/SwyxTray/SwyxTray.csproj",
"-c",
"Debug",
// Das Paket Swyx.Client.ClmgrAPI waehlt die Interop-Assembly ueber
// $(Platform) und bricht bei AnyCPU ab. Die csproj setzt x64 bereits
// als Vorgabe; hier steht es noch einmal, damit die Aufgabe auch dann
// uebersetzt, wenn jemand die Vorgabe aendert.
"-p:Platform=x64",
"-consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile",
"group": { "kind": "build", "isDefault": true }
},
{
"label": "build (Release)",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/SwyxTray/SwyxTray.csproj",
"-c",
"Release",
"-p:Platform=x64",
"-consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile",
"group": "build"
},
{
// Beendet eine laufende Instanz — egal in welcher Sitzung. Ohne das
// schluege ein Start still fehl: die Einzelinstanz-Sperre laesst den
// zweiten Prozess kommentarlos enden.
"label": "SwyxTray beenden",
"command": "powershell",
"type": "process",
"args": [
"-NoProfile",
"-Command",
// Wait-Process: erst zurueckkehren, wenn der Prozess wirklich weg ist —
// sonst sieht der nachfolgende Start noch die Leiche in Get-Process.
// Das abschliessende 'exit 0' ist Pflicht: findet Get-Process keinen
// Prozess, steht $? auf false, und powershell -Command macht daraus
// sonst Exit-Code 1 — die Kette briche ab, obwohl nichts zu tun war.
"$p = Get-Process SwyxTray -ErrorAction SilentlyContinue; if ($p) { $p | Stop-Process -Force; $p | Wait-Process -Timeout 5 -ErrorAction SilentlyContinue }; exit 0"
],
"problemMatcher": []
},
{
// Startet die App in der DESKTOP-Sitzung des angemeldeten Benutzers —
// noetig, wenn VS Code remote verbunden ist. Warum, steht im Skript.
"label": "SwyxTray im Desktop starten (Debug)",
"dependsOrder": "sequence",
"dependsOn": ["SwyxTray beenden", "build (Debug)"],
"command": "powershell",
"type": "process",
"args": [
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-File",
"${workspaceFolder}/.vscode/start-desktop.ps1",
"-Exe",
"${workspaceFolder}/src/SwyxTray/bin/x64/Debug/net10.0-windows/win-x64/SwyxTray.exe"
],
"problemMatcher": []
}
]
}