How to handle a blocked clipboard and other oddities

前端 未结 8 1967
闹比i
闹比i 2020-12-02 10:03

Over the course of the last couple of hours I have been tracking down a fairly specific bug with that occurs because another application has the clipboard open. Essentially

相关标签:
8条回答
  • 2020-12-02 10:35

    I've actually come up with my own solution and it seems to be working for me.

    // This allows the clipboard to have something copied to it.
        public static void ClipboardPaste(String pasteString)
        {
            // This clears the clipboard
            Clipboard.Clear();
    
            // This is a "Try" of the statement inside {}, if it fails it goes to "Catch"
            // If it "Catches" an exception. Then the function will retry itself.
            try
            {
                // This, per some suggestions I found is a half second second wait before another
                // clipboard clear and before setting the clipboard
                System.Threading.Thread.Sleep(500);
                Clipboard.Clear();
                // This is, instead of using SetText another method to put something into
                // the clipboard, it includes a retry/fail set up with a delay
                // It retries 5 times with 250 milliseconds (0.25 second) between each retry.
                Clipboard.SetDataObject(pasteString, false, 5, 250);
            }
            catch (Exception)
            {
                ClipboardPaste(pasteString);
            }
        }
    

    This is obviously C#, however these methods are exposed to all Visual Studios. I have obviously created a looping function, as well as attempted to force it into the clipboard with retries.

    Essentially here's the flow. Let's say you want to place the word clipboard into the clipboard, anywhere in your code (assuming this function is defined).

    1. Call function ClipboardPaste("Clipboard");
    2. It will then clear the clipboard
    3. Then it will "try" to put your string into the clipboard.
    4. First it waits half a second (500 milliseconds)
    5. Clears the clipboard again
    6. Then it tries to put the string into the clipboard using SetDataObject
    7. SetDataObject if it fails will retry up to five times, with a 250 millisecond delay in between each retry.
    8. If the initial attempt fails, it catches the exception, the crash, then it tries it all over again.

    Yes, this does have a flaw if you know your clipboard will always have an exception no matter what (infinite loop). However I have not run into an infinite loop with this method yet. The other flaw is that it can take a couple of seconds (essentially slowing down your applications) before it will work, while it's attempting it may freeze your application, once it succeeds the application will continue anyway.

    0 讨论(0)
  • 2020-12-02 10:39

    Just call this first:

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern IntPtr CloseClipboard();
    

    I noticed that if you're in the middle of a paste operation (WM_PASTE message), including during the TextChanged event, the clipboard remains locked by the window (the TextBox) receiving the event. So if you just call that "CloseClipboard" method inside the event handler, then you can call the managed Clipboard.Clear and Clipboard.SetText methods without any issues or delays.

    0 讨论(0)
提交回复
热议问题