Clipboard.SetDataObject fails on some machines...

  • Thread starter Thread starter Tony
  • Start date Start date
T

Tony

When using Clipboard.SetDataObject (string, true) a COM exception occurs,
"The requested clipboard operation failed. (800401D0)". If the same call is
made again, it works without issue. Note the exception *only* occurs if the
second parameter is set to "true".

This exception only occurs on *some* servers (Win2003) but not all.

Any ideas? .

Here is a sample console application which generates the exception.

C:\temp>CopyToClipBoard.exe true
saveContents = True
Exception caught from 1st copy: The requested clipboard operation failed.
(800401D0)
Attempting second copy. Press ENTER to continue.

All Done!

C:\temp>CopyToClipBoard.exe false
saveContents = False
Attempting second copy. Press ENTER to continue.

All Done!

C:\temp>
[STAThread]

static void Main(string[] args)

{

const string DEFAULT_STR = "Hello everybody!";

bool saveContents = ((args.Length > 0) && (args[0].ToLower () == "true"));

Console.WriteLine ("saveContents = " + saveContents);

try

{

System.Windows.Forms.Clipboard.SetDataObject (DEFAULT_STR + ": Attempt #1",
saveContents);

}

catch (System.Runtime.InteropServices.ExternalException ex)

{

Console.WriteLine ("Exception caught from 1st copy: {0} ({1:X})",
ex.Message, ex.ErrorCode);

}


Console.WriteLine ("Attempting second copy. Press ENTER to continue.");

Console.ReadLine ();

try

{

System.Windows.Forms.Clipboard.SetDataObject (DEFAULT_STR + ": Attempt #2",
saveContents);

}

catch (System.Runtime.InteropServices.ExternalException ex)

{

Console.WriteLine ("Exception caught from 2nd copy: {0} ({1:X})",
ex.Message, ex.ErrorCode);

}

Console.WriteLine ("All Done!");

}
 
Looking through Google, there have been several instances of this occurring,
but never a resolution. I found one, so I thought I'd post it for future
generations.<g>

I opened a Dev PSS case to resolve this issue. Here is MS's response...

"I've found one known issue with Clipboard.SetDataObject where
System.Runtime.Interopservices.ExternalException : The requested clipboard
operation has failed is thrown by current version of .NET framework in case
another thread is accessing the Clipboard at the same time. When the same
call is made again, it will succeed with no error.
To workaround this problem, in the next version of .NET framework (2.0?),
there is going to be an overloaded method for SetDataObject
Clipboard.SetDataObject(object data, bool copy, int retryTimes, int
retryDelay) that takes in two extra parameters #of retrys and the delay
between retries. Please let me know if you think you may be encountering
similar situation and if you have any further questions/concerns regarding
this issue. "

I wonder if it is the Terminal Server (aka Remote Desktop) client that could
be the issue? Still not sure why it happens on a few machines, but not
others. I suspect its a strange race condition.

Here is my work around code...
[STAThread]
static void Main(string[] args)

{

const string DEFAULT_STR = "Hello everybody!";

bool saveContents = ((args.Length > 0) && (args[0].ToLower () == "true"));


int CLIPBOARD_COPY_ATTEMPTS = (args.Length > 1) ? Convert.ToInt32 (args[1])
: 2;

int CLIPBOARD_RETRY_DELAY_MS = (args.Length > 2) ? Convert.ToInt32 (args[2])
: 499;

Console.WriteLine ("saveContents = " + saveContents);

Console.WriteLine ("attempts = " + CLIPBOARD_COPY_ATTEMPTS);

Console.WriteLine ("delay = " + CLIPBOARD_RETRY_DELAY_MS);


int attempt = 1;

try

{

do

{

try

{

Console.WriteLine ("Performing attempt number {0}.", attempt);

System.Windows.Forms.Clipboard.SetDataObject (DEFAULT_STR + attempt,
saveContents);

// if we get here, the setdataobject call worked, which means we can exit
the do loop

break;

}

catch (System.Runtime.InteropServices.ExternalException ex)

{

const int OPEN_CLIPBOARD_FAILED = -2147221040;

Console.WriteLine ("Exception caught from attempt, {0}: {1} ({2:X})",
attempt, ex.Message, ex.ErrorCode);

Console.WriteLine ("Dump: {0}", ex.ToString ());


// if this error occurs _and_ we have not exceeded out attempt count, do the
loop again after sleeping for a bit

if ((ex.ErrorCode == OPEN_CLIPBOARD_FAILED) && (attempt <
CLIPBOARD_COPY_ATTEMPTS))

{

Console.WriteLine ("Sleeping for {0} mS.", CLIPBOARD_RETRY_DELAY_MS);

System.Threading.Thread.Sleep (CLIPBOARD_RETRY_DELAY_MS);

++attempt;

continue; // to my surprise, this actually works from inside a catch block.

}

// unknown ErrorCode or we have exceeded our attempts, so let the outer
try/catch deal with it.

throw ex;

}

} while (attempt <= CLIPBOARD_COPY_ATTEMPTS);

}

catch (Exception ex)

{

// catch any unhandled exceptions thrown by the inner loop.

Console.WriteLine ("Unhandled exception: " + ex.Message);

}

Console.WriteLine ("All Done!");

}


--
Tony
Tony said:
When using Clipboard.SetDataObject (string, true) a COM exception occurs,
"The requested clipboard operation failed. (800401D0)". If the same call
is made again, it works without issue. Note the exception *only* occurs
if the second parameter is set to "true".

This exception only occurs on *some* servers (Win2003) but not all.

Any ideas? .

Here is a sample console application which generates the exception.

C:\temp>CopyToClipBoard.exe true
saveContents = True
Exception caught from 1st copy: The requested clipboard operation failed.
(800401D0)
Attempting second copy. Press ENTER to continue.

All Done!

C:\temp>CopyToClipBoard.exe false
saveContents = False
Attempting second copy. Press ENTER to continue.

All Done!

C:\temp>
[STAThread]

static void Main(string[] args)

{

const string DEFAULT_STR = "Hello everybody!";

bool saveContents = ((args.Length > 0) && (args[0].ToLower () == "true"));

Console.WriteLine ("saveContents = " + saveContents);

try

{

System.Windows.Forms.Clipboard.SetDataObject (DEFAULT_STR + ": Attempt
#1", saveContents);

}

catch (System.Runtime.InteropServices.ExternalException ex)

{

Console.WriteLine ("Exception caught from 1st copy: {0} ({1:X})",
ex.Message, ex.ErrorCode);

}


Console.WriteLine ("Attempting second copy. Press ENTER to continue.");

Console.ReadLine ();

try

{

System.Windows.Forms.Clipboard.SetDataObject (DEFAULT_STR + ": Attempt
#2", saveContents);

}

catch (System.Runtime.InteropServices.ExternalException ex)

{

Console.WriteLine ("Exception caught from 2nd copy: {0} ({1:X})",
ex.Message, ex.ErrorCode);

}

Console.WriteLine ("All Done!");

}
 
Back
Top