tags:

views:

950

answers:

3

Why does the following code sometimes causes an Exception with the contents "CLIPBRD_E_CANT_OPEN":

Clipboard.SetText(str);

This usually occurs the first time the Clipboard is used in the application and not after that.

A: 

I think your question is being voted down because there's no clear question being asked here.

Are you asking if there's a way around this? If that's what you're asking, I'd recommend looking into using direct Win32 clipboard APIs if it is indeed .NET's implementation of the clipboard that's causing the issue.

edit According to this, it's a bug in TS, not .NET's clipboard implementation.

Judah Himango
+2  A: 

Actually, I think this is the fault of the Win32 API.

http://blogs.msdn.com/ts/archive/2006/11/20/why-does-my-shared-clipboard-not-work-part-2.aspx

To set data in the clipboard, you have to open it first. Only one process can have the clipboard open at a time. So, when you check, if another process has the clipboard open for any reason, your attempt to open it will fail.

It just so happens that Terminal Services keeps track of the clipboard, and on older versions of Windows (pre-Vista), you have to open the clipboard to see what's inside... which ends up blocking you. The only solution is to wait until Terminal Services closes the clipboard and try again.

It's important to realize that this is not specific to Terminal Services, though: it can happen with anything. Working with the clipboard in Win32 is a giant race condition. But, since by design you're only supposed to muck around with the clipboard in response to user input, this usually doesn't present a problem.

Tadmas
+1  A: 

This is caused by a bug/feature in Terminal Services clipboard (and possible other things) and the .NET implementation of the clipboard. A delay in opening the clipboard causes the error, which usually passes within a few milliseconds.

The solution is to try multiple times within a loop and sleep in between.

for (int i = 0; i < 10; i++) { try { Clipboard.SetText(str); return; } catch { } System.Threading.Thread.Sleep(10); }

Robert Wagner
If you look at the internals of Clipboard.SetText, on .NET 2.0 SP1 at least, you'll see it already has a retry/wait loop. Retries up to 10 times with a 100ms delay.
Mike Dimmick
@Mike: System.Windows.Forms.Clipboard has a retry, but System.Windows.Clipboard from WPF doesn't.
Cameron MacFarland