Get the origin data source with System.Windows.Cli

2019-03-03 18:31发布

问题:

I am using System.Windows.Clipboard to copy some text, and I would like to know is there a chance to get the origin source, e.g. a the file where I copyied it from, or the website, folder.... ?

Thanks

回答1:

GetClipboardOwner() can be used to get the Handle of the Window that last placed data into the Clipboard.

The returned handle is then passed to GetWindowThreadProcessId() to get the Process ID and Thread ID of that Window.

The Process ID is the parameter to pass to the .Net System.Diagnostics.Process.GetProcessById() method to retrieve the information needed.

Note that you have to build a 64bit application to fully inspect a 64bit process. If your project has the Prefer 32-bit option set, some information will not be available.

Windows API declarations. The overloaded GetClipboardOwnerProcessID() wrapper method returns the ProcessID of the ClipBoard Owner and, optionally, its Thread ID.

public class WinApi
{
    [SuppressUnmanagedCodeSecurityAttribute]
    internal static class SafeNativeMethods
    {
        [DllImport("user32.dll")]
        public static extern IntPtr GetClipboardOwner();
    }

    [SuppressUnmanagedCodeSecurityAttribute]
    internal static class UnsafeNativeMethods
    {
        //The return value is the identifier of the thread that created the window. 
        [DllImport("user32.dll", SetLastError = true)]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    }

    //Wrapper used to return the Window processId
    public static uint GetClipboardOwnerProcessID()
    {
        uint processId = 0;
        UnsafeNativeMethods.GetWindowThreadProcessId(SafeNativeMethods.GetClipboardOwner(), out processId);
        return processId;
    }

    //Overload that returns a reference to the Thread ID
    public static uint GetClipboardOwnerProcessID(ref uint threadId)
    {
        uint processId = 0;
        threadId = UnsafeNativeMethods.GetWindowThreadProcessId(SafeNativeMethods.GetClipboardOwner(), out processId);
        return processId;
    }
}


The wrapper can be called like this, if you just need the Process Id:

uint ClipBoadrOwnerProcessId = WinApi.GetClipboardOwnerProcessID();

Or this way, if you also need the Thread Id:

uint ClipBoadrOwnerThreadId = 0;
uint ClipBoadrOwnerProcessId = WinApi.GetClipboardOwnerProcessID(ref ClipBoadrOwnerThreadId);

Pass the returned value to the Process.GetProcessById() method:

Process ClipBoardOwnerProcess = Process.GetProcessById((int)WinApi.GetClipboardOwnerProcessID());

string ProcessName = ClipBoardOwnerProcess.ProcessName;
string ProcessWindowTitle = ClipBoardOwnerProcess.MainWindowTitle;
string ProcessFileName = ClipBoardOwnerProcess.MainModule.FileName;
//(...)


If you copy some text from your browser, the ProcessName will be the name of your browser and the ProcessFileName the path to its executable.