Clipboard.Clear() problem

G

Guest

My Clipboard is getting into some very confused state where I can't even
clear it. No applications can access the clipboard in this state, and if I
run Clipboard.Clear() I get:

System.Runtime.InteropServices.ExternalException: Requested Clipboard
operation did not succeed.
at System.Windows.Forms.Clipboard.ThorwIfFailed(Int32 hr)
at System.Windows.Forms.Clipbard.SetDataObject(Object data, Boolean copy,
Int 32 retryTimes, Int32 retryDelay)
at System.Windows.Forms.Clipboard.Clear()

Is there some lower-level code or external procedure I can use to forcibly
clear or reset the clipboard?
 
M

Marc Gravell

Some (all?) of the clipboard operations require an STA; are you perhaps
running as an MTA? Try adding [STAThread] to your Main() method - see if
this helps.

Marc
 
G

Guest

Yes, I'm running it in [STAThread]. (I had gotten a separate complaint for
that earlier on.)
 
W

Walter Wang [MSFT]

Hi,

NET Clipboard.Clear() internally calls Win32 API OleSetClipboard() to
clear the clipboard content.

#OleSetClipboard
http://windowssdk.msdn.microsoft.com/en-us/library/ms686623.aspx

When an application opens the clipboard (either directly or indirectly by
calling the Win32 OpenClipboard function), the clipboard cannot be used by
any other application until it is closed. If the clipboard is currently
open by another application, OleSetClipboard fails.

You can verify this by creating a simple program which opens the clipboard:

if (OpenClipboard(hWnd)) {
::MessageBox(hWnd, _T("Clipboard opened, no other application can
change the content of clipboard."), _T("Message"), 0);
CloseClipboard();
}

When the message box is shown, call Clipboard.Clear() from .NET will fail
with the exception you're experiencing.

From OpenClipboard()'s documentation:

#OpenClipboard
http://windowssdk.msdn.microsoft.com/en-us/library/ms649048.aspx

You can also see this statement: OpenClipboard fails if another window has
the clipboard open.

So your issue seems some other application is opening the clipboard and
forget to call CloseClipboard() properly.

I hope this helps. Please feel free to post here if anything is unclear.

Sincerely,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

OK, that is helpful, but since I can't figure out which process has stolen
the clipboard is there any way (doesn't have to be programmatic -- I'm that
desperate!) for me to forcibly reset or restart the clipboard so that I can
use it again?

Right now my only solution when the clipboard has been hijacked seems to be
to restart the computer!
 
W

Walter Wang [MSFT]

Hi,

When an application opened the clipboard, as far as I know, other
applications can only open the clipboard when the application closes it (or
the application exits).

You can use following code to determine which process is currently opening
the clipboard:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ConsoleApplication1
{
class Program
{
[DllImport("user32.dll")]
static extern IntPtr GetOpenClipboardWindow();

[DllImport("user32.dll", SetLastError = true)]
static extern int GetWindowThreadProcessId(IntPtr hWnd, out int
lpdwProcessId);

static void Main(string[] args)
{
IntPtr hwnd = GetOpenClipboardWindow();
if (hwnd != IntPtr.Zero)
{
int processId;
GetWindowThreadProcessId(hwnd, out processId);
Process p = Process.GetProcessById(processId);
Console.WriteLine(p.Modules[0].FileName);
}
}
}
}

I hope this helps. Please feel free to post here if anything is unclear.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Wow, perfect! I never would have found the rogue process without that code.
Thanks a million!
 
B

Bugblatter

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top