About Terminal Server, Citrix, Delphi and other stuff
Did you ever loose Clipboard functionality (copy/paste) while working with several Terminal Server sessions? I think everyone that works a lot with Terminal Server has experienced this from time to time.
It’s caused by badly behaving applications. Dimitry Vostokov wrote a tool to fix this issue for Citrix (RepairCBDChain.exe), he explains the issue very well on his blog:
Windows has a mechanism to notify applications about clipboard changes. An application interested in such notifications has to register itself in the so called clipboard chain. Windows inserts it on top of that chain and that application is responsible to propagate changes down the chain:
If 3rd-party application forgets to forward notifications down then we have a broken clipboard chain and clipboard changes are not sent via ICA protocol:
Read more at Dimitry’s Blog: http://citrite.org/blogs/dmitryv/2006/12/09/clipboard-issues-explained/
So how can we fix this for Terminal Server then?
MSTSC creates a hidden window with Window Class RdpClipRdrWindowClass, you can observe this with a Window Spy tool such as X-Spy
If we look at the Window Style we can see the Window is hidden (doesn’t contain WS_VISIBLE):
So we just need to find all windows with this Windows Class and subscribe them to Clipboard Notifications.
The code is simple:
function EnumWindowsProc(hHwnd: HWND; Param:Integer): boolean; stdcall;
var ClassName: String;
SetLength(ClassName, GetClassName(hHWnd, PChar(ClassName), 255));
if ClassName = 'RdpClipRdrWindowClass' then
// This is uses to restore the clipboard functionality
Result := True;
Using EnumWindows instead of FindWindow (as RepairCBDChain seems to do) has the advantage that it finds multiple windows (when you have multiple sessions) and not just the first.
You can download the compiled version below. If you like it why not leave a comment?
RDP Clipboard Fix (10266)
See here for more Terminal Server related articles: http://remkoweijnen.nl/blog/topics/terminalserver/
There’s an explanation of this issue at the Microsoft Terminal Services team blog too:
.NET .NET FrameWork Active Directory Altiris Automation Manager Citrix Dell Delphi Excel Exchange Exchange2003 Exchange2010 Hack HP iOS Java LinkedIn Linux Lync Management Pack MSI Office Office 2010 Passat Password PowerPoint PowerShell RES RNS510 SasLibEx SCOM Security Terminal Server ThinApp TSAdminEx VBS VCDS Visual Basic Visual Studio VMWare Volkswagen VSAE Windows PE Wordpress XenApp