Plandent MSTSC Script Hook
Kleines Windows-Projekt, das beim erfolgreichen Aufbau einer klassischen RDP-Verbindung mit mstsc.exe lokal ein konfiguriertes Script startet.
Komponenten
- PlandentMstscScriptHook.dll – native x64 DVC-Plugin-DLL für den Remote Desktop Connection Client.
- PlandentMstscScriptHook.exe – WinForms-Konfigurator/Installer. Die Release-EXE enthält die DLL als Resource und extrahiert sie bei der Installation.
Verhalten
Die DLL implementiert IWTSPlugin und exportiert VirtualChannelGetInstance.
Initialize()– Plugin wird von MSTSC initialisiert.Connected()– liest die Konfiguration und startet das lokale Script.Disconnected()– beendet das von dieser Plugin-Instanz gestartete Script, wennStopOnDisconnect=1gesetzt ist.Terminated()– bereinigt Prozesshandles; beiStopOnDisconnect=0läuft das Script weiter.
Der Plugin-Callback wartet nicht auf das Script. Es wird nur mit CreateProcessW gestartet und der Callback kehrt direkt zurück.
Registry
MSTSC-Registrierung pro Benutzer:
HKCU\Software\Microsoft\Terminal Server Client\Default\AddIns\PlandentMstscScriptHook
Name = C:\Users\<Benutzer>\AppData\Local\Plandent\MstscScriptHook\PlandentMstscScriptHook.dll
Konfiguration:
HKCU\Software\Plandent\MstscScriptHook
Enabled REG_DWORD 1
ScriptPath REG_EXPAND_SZ C:\RemoteVDDS\RemoteVDDS_Receiver_TS.bat
Arguments REG_SZ MIN
WorkingDirectory REG_EXPAND_SZ C:\RemoteVDDS
StartOnConnect REG_DWORD 1
StopOnDisconnect REG_DWORD 0
Hidden REG_DWORD 1
PreventDuplicates REG_DWORD 1
EnableLogging REG_DWORD 1
Unterstützte Starttypen
.bat/.cmd→cmd.exe /D /S /C ....ps1→ Windows PowerShell mit-NoProfile -NonInteractive -ExecutionPolicy Bypass -File ....exe→ direkter Start
Bei Hidden=1 wird CREATE_NO_WINDOW verwendet und SW_HIDE gesetzt.
Mehrfachstartschutz
Bei PreventDuplicates=1 wird aus dem expandierten Scriptpfad ein Named Mutex erzeugt. Das Mutex-Handle wird gezielt an den gestarteten Prozess vererbt. Damit bleibt der Schutz bestehen, solange der Receiver läuft – auch wenn die ursprüngliche mstsc.exe-Instanz bereits beendet wurde.
Der Schutz ist bewusst Local\\..., also auf die lokale Windows-Sitzung begrenzt.
Logging
Bei aktiviertem Logging:
%LOCALAPPDATA%\Plandent\MstscScriptHook\plugin.log
Die GUI enthält einen Button Log öffnen.
Voraussetzungen zum Bauen
- Windows 10/11 x64
- Visual Studio 2022 oder Visual Studio Build Tools 2022
- Workload Desktopentwicklung mit C++
- Windows 10/11 SDK
- .NET 8 SDK
Release bauen
PowerShell im Projektverzeichnis:
.\build-release.ps1 -Clean
Ergebnis:
dist\PlandentMstscScriptHook.exe
Die veröffentlichte EXE ist x64, self-contained und enthält die native Plugin-DLL als Resource.
Installation
PlandentMstscScriptHook.exestarten.- Script über
...auswählen. - Für
RemoteVDDS_Receiver_TS.batals ArgumentMINsetzen. - Optional Arbeitsverzeichnis auswählen; standardmäßig sollte es dem Scriptverzeichnis entsprechen.
- Script testen und anschließend Test beenden.
- Plugin installieren anklicken.
- Alle bereits laufenden
mstsc.exe-Instanzen schließen. - MSTSC neu starten und eine RDP-Verbindung herstellen.
Die Installation erfolgt nur unter HKCU und %LOCALAPPDATA%; dafür sind normalerweise keine Administratorrechte nötig.
Deinstallation
Plugin entfernen löscht den MSTSC-Registryeintrag und die installierte DLL. Ist die DLL noch in einer laufenden mstsc.exe geladen, wird zumindest die Registrierung entfernt; nach dem Schließen aller MSTSC-Instanzen kann die DLL erneut über den Button entfernt werden.
Die Script-Konfiguration unter HKCU\Software\Plandent\MstscScriptHook bleibt absichtlich erhalten.
Wichtige Grenzen
- Das Plugin ist für den klassischen Microsoft RDC-Pluginmechanismus ausgelegt. Andere RDP-Clients müssen diesen Mechanismus ebenfalls unterstützen, sonst wird die DLL nicht geladen.
StopOnDisconnectbeendet nur den vom Plugin selbst gestarteten Root-Prozess. Beim RemoteVDDS-BAT ist das der dauerhaft laufendecmd.exe-Receiver.- Das Script läuft mit den Rechten des lokalen Benutzers, der
mstsc.exegestartet hat. - AppLocker/WDAC oder andere Application-Control-Richtlinien können das Laden einer nicht signierten DLL bzw. das Starten des Scripts blockieren.