Skip to content

microsoft/rdp-dvc-plugin-samples

languages products description urlFragment page_type name
cpp
csharp
go
python
rust
javascript
windows
Samples demonstrating Remote Desktop Protocol (RDP) Dynamic Virtual Channel (DVC) plugins across multiple languages and activation models.
rdp-dvc-plugin-samples
sample
RDP DVC plugin samples

RDP DVC Plugin Samples

Samples for Remote Desktop Protocol (RDP) Dynamic Virtual Channels (DVC) across multiple languages and activation models. Each sample is self-contained: build scripts, protocol, client plugin, and server live together.

These samples model the “two cooperating parts” for RDP virtual channels: a client-side module loaded by the RDP client, and a server-side module running in the remote session; the RDP transport multiplexes multiple virtual channels alongside display/input traffic.

Contents

File/folder Description
Simple/ Minimal ping/echo protocol samples.
Advanced/ Full-featured samples with session lifecycle and Protocol Buffers.
BUILD_MATRIX.md Per-language build requirements matrix.
TROUBLESHOOTING.md Troubleshooting guide.
README.md This README file.

How to choose:

  • New to DVCs: start with Simple.
  • Need multiple activation models or protobuf-style framing: pick Advanced.
  • Language-specific work: open the README under that language folder.

Running the sample

  1. Pick a language under Simple/ or Advanced/ and open its README.
  2. Register the client plugin on the RDP client machine (per-user or per-machine as noted).
  3. Connect with an RDP client; the channel opens automatically.
  4. Start the server inside an RDP session on the remote machine.

At a high level, every sample follows the same handshake: register/enable the client plugin on the client machine (the machine running the RDP client), establish an RDP connection, and then run the server application inside the remote session so it can open a DVC endpoint and exchange data. That separation (client plugin vs server app) is the core virtual-channel model.

Client plugin activation modes

  • LocalServer COM (out-of-proc, recommended)
    • AddIns key points to CLSID; CLSID\LocalServer32 points to the EXE.
    • You can launch it before the RDP client or let COM activate it via CLSID/-Embedding.
    • Register before starting the RDP client; isolates crashes away from the RDP client.
  • In-process COM (DLL)
    • AddIns key points to CLSID; CLSID\InprocServer32 points to the DLL.
    • Runs inside the RDP client process; instability can take down the client. Use only when in-proc is required.
  • LoadLibrary / VirtualChannelGetInstance
    • AddIns key points directly to a DLL; the RDP client loads it and calls the export.
    • Minimal registration but same in-proc stability trade-offs as COM DLL.

DVC session and channel lifecycle (high level)

  • Server side (in-session): open the DVC for the active session only. Advanced samples show checking session state (WTSQuerySessionInformation) and subscribing to logon/disconnect (WTSRegisterSessionNotificationEx) so you reopen on reconnect.
  • Notification flow: subscribe → on logon/unlock, find active SessionId → open channel (WTSVirtualChannelOpenEx) → on disconnect/logoff, close and wait for the next active session.
  • Client side (RDP client plugin): IWTSPlugin::InitializeCreateListenerIWTSListenerCallback::OnNewChannelConnection → per-connection IWTSVirtualChannelCallback handles data.
  • Data plane: server uses WTS APIs (WTSVirtualChannelRead/Write) or file-handle mode; client handles OnDataReceived and responds via IWTSVirtualChannel::Write.

Next steps

About

Examples of RDP Dynamic Virtual Channel plugins across 7 languages and multiple COM activation models. Each implementation is fully self-contained with build scripts, protocol definitions, client plugins, and server applications.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors