JMC17
JMC17

Reputation: 381

Clipboard already in use by Idle.exe

I've been working on a program that uses mouse and keyboard simulation and often has to grab/set clipboard data.

I've ran into the problem apparently many people runs into, the clipboard is being used by another process so "Clipboard.SetDataObject" throws the exception "Requested Clipboard operation did not succeed."

       private void CheckSetClipboard(string s)
    {
        IntPtr ClipWindow = GetOpenClipboardWindow();
        if (ClipWindow != null && ClipWindow != (IntPtr)0)
        {
            uint wid;
            GetWindowThreadProcessId(ClipWindow, out wid);
            Process p = Process.GetProcessById((int)wid);
            Console.WriteLine("Process using Clipboard: " + p.ProcessName);
        } else {
            Console.WriteLine("ClipWindow:" + ClipWindow.ToString());
        }
            OpenClipboard(IntPtr.Zero);
            EmptyClipboard();
            CloseClipboard();
        try { Clipboard.SetDataObject(s, true, 10, 50); }
        catch{// Clipboard.SetDataObject(s, true, 10, 50);
        }
    }

I tried a few solutions as the code above shows but eventually the error pops up again. This time I decided to go full ham on it and got the process name of the process using the clipboard..
This is what the console showed:

Process using Clipboard: Idle

How is Idle.exe using the clipboard?
Can I even kill that process to release the clipboard?
Am I doing something wrong?

In the end, I just want to be able to do clipboard operations without failures. Ctrl+c and Ctrl+v never fails, why does my c# code does?

More info:
The data i'm passing into the clipboard is "-0.09261441" or similar numbers.
The error always occurs on the catch{...} part.

[SOLVED] Thanks to Hans, I was able to figure it out. I misinterpreted the tip and sample code on pinvoke. Those two clipboard operations in that try{}catch{} were apparently conflicting in some way. The proper way would have been to use try{}catch{try{}catch{}} which I didn't use and didn't test.

My problems seems to have solved themselves for now when I commented out the second clipboard operation.

Upvotes: 0

Views: 482

Answers (1)

M.Hassan
M.Hassan

Reputation: 11032

I created a Dispossable class with your code(with some change), and filled the missing methods and run without problem and no hang. I test in a winform application.

I call the method from the button and copy from one textbox , and paste the value in another textbox and the result of paste is valid without hanging. Note how i disposed the handle automatic by making the class inherit from IDisposable.

try this code

 class ClipboardUtility : IDisposable
{
    private bool disposed = false;

    //If the function succeeds, the return value is the handle to the window that has the clipboard open. 
    //If no window has the clipboard open, the return value is NULL. 
    //To get extended error information, call GetLastError. 

    [DllImport("user32.dll")]
    static extern IntPtr GetOpenClipboardWindow();

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

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool OpenClipboard(IntPtr hWndNewOwner);

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool CloseClipboard();
    [DllImport("user32.dll")]
    static extern bool EmptyClipboard();

    private IntPtr ClipWindow;
    public void CheckSetClipboard(string s)
    {

        //IntPtr ClipWindow = GetOpenClipboardWindow();
          ClipWindow = GetOpenClipboardWindow();
        Console.WriteLine("handle IntPtr= {0}", ClipWindow);
        //  if (ClipWindow != null && ClipWindow != (IntPtr)0)
        if (ClipWindow != null )
        {
            Console.WriteLine("ClipWindow_" + ClipWindow.ToString());
            uint wid = GetWindowThreadProcessId(ClipWindow, out wid);
            Process p = Process.GetProcessById((int)wid);
            Console.WriteLine("Process using Clipboard: " + p.ProcessName);
        }
        else
        {
            Console.WriteLine("error: {0}", Marshal.GetLastWin32Error());
          //  Console.WriteLine("0 is not idle");
        }

        //Marshal.FreeHGlobal(ClipWindow);
        //OpenClipboard(IntPtr.Zero);
        //EmptyClipboard();
        //CloseClipboard();
        //Console.WriteLine("s: " + s);

        try
        {
            Clipboard.SetDataObject(s, true, 10, 50);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
           // Clipboard.SetDataObject(s, true, 10, 50);
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            CloseHandle(ClipWindow);

            ClipWindow = IntPtr.Zero;

            disposed = true;

        }
    }

    [DllImport("Kernal32")]
    private extern static Boolean CloseHandle(IntPtr handle);
}

Upvotes: 1

Related Questions