Link to home
Start Free TrialLog in
Avatar of trevor1940
trevor1940

asked on

C#: Copy to clipboard Exception

On my form I have a CopyBTN  this Copies the contents of a RichTextBox to the clipboard any suggestions why it sometimes fails yet if in debug you can just continue for it to work
How do I capture this exception?
FYI there is lines of text in ResultsRTB.Text

        private void CopyBTN_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(ResultsRTB.Text);
        }

Open in new window


Error

System.Runtime.InteropServices.ExternalException was unhandled
  ErrorCode=-2147221040
  HResult=-2147221040
  Message=Requested Clipboard operation did not succeed.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.Clipboard.ThrowIfFailed(Int32 hr)
       at System.Windows.Forms.Clipboard.SetDataObject(Object data, Boolean copy, Int32 retryTimes, Int32 retryDelay)
       at System.Windows.Forms.Clipboard.SetText(String text, TextDataFormat format)
       at System.Windows.Forms.Clipboard.SetText(String text)
       at Trevor.Form1.CopyBTN_Click(Object sender, EventArgs e) in D:\Vb\Trevor\Trevor\Form1.cs:line 265
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Trevor.Program.Main() in D:\Vb\Trevor\Trevor\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

Open in new window

Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

My guess is that something had the clipboard open when you tried to access it. The Windows clipboard is basically one central location, and when you get or set the text, it's like you're opening a file, getting/setting the content, and then closing the file. And if something else still has the clipboard open when you try to get/set the content, you'll get an error.
Avatar of trevor1940
trevor1940

ASKER

So how would I program this, put it in a try catch finally block with a delay on the exception?

something like this??

        private void CopyBTN_Click(object sender, EventArgs e)
        {
            try
              {
                 Clipboard.SetText(ResultsRTB.Text);
              }
           catch  (Exception e)
              {
                    int milliseconds = 500;
                    Thread.Sleep(milliseconds);
              }
            finally
              {
                 Clipboard.SetText(ResultsRTB.Text);
              }

        }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The "finally" clause runs at the end, no matter what,
Errrr...  almost no matter what.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally

Within a handled exception, the associated finally block is guaranteed to be run. However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. That, in turn, is dependent on how your computer is set up.

For all practical purposes, it runs no matter what.
Good point. :)
Thank you
i'm sure this technique will come in handy again
Didn't quite understand kaufmed  point

Other than The "finally" clause runs at the end so don't attempt to run code here that could fail / or be the the cause of an exception
kaufmed was pointing out that there are times where the "finally" clause won't run. These situations are pretty rare, and the vast majority are related to a scenario where your app is pretty much going to crash or shutdown in some way, and there's no avoiding it. I can't think of any common situation where this isn't the case (where you wouldn't hit the finally block but your app would keep running afterwards).

One example would be a stack overflow exception. An example would be like this:
        public Form1()
        {
            InitializeComponent();
            InfinitelyRecursingMethod();
        }

        private void InfinitelyRecursingMethod()
        {
            try
            {
                // Recursing infinitely will eventually result in a stack overflow
                InfinitelyRecursingMethod();
            }
            catch(Exception ex)
            {
                Console.WriteLine("Exception caught");
            }
            finally
            {
                Console.WriteLine("FINALLY!");
            }
        }

Open in new window


If you attach a debugger and break on the catch and finally lines, you'll notice they're not hit - the stack overflow pretty much says, "Sorry - I'm outta room to do anything more!" and exits.