I think your problem is due to timing.
To adjust the focus focus and make the actual copy to the clipboard, you need to wait until the window becomes focus, and wait for the clipboard to update.
There are several ways to deal with these ugly win32 things.
For clipboard contents. I am comparing the source content with the current content. I set the original content to string.empty if its image or some other is not text data. Then I wait for a function that checks the clipboard for changes.
For SetForegroundWindow, I am currently adding a delay in my asynchronous function. You can probably also find the win32 api call to wait until this window is correctly placed in the foreground.
I do both of them in async functions and wait for it so that there is no block.
SendKeys should work with SendWait ("^ c"). SendWait ("^ (c)") will not always work as indicated in other answers. However, copying ctrl + c to the clipboard does not happen instantly.
Point p; if (GetCursorPos(out p)) { IntPtr ptr = WindowFromPoint(p); if (ptr != IntPtr.Zero) { SetForegroundWindow(ptr); //wait for window to get focus quick and ugly // probably a cleaner way to wait for windows to send a message // that it has updated the foreground window await Task.Delay(300); //try to copy text in the current window SendKeys.Send("^c"); await WaitForClipboardToUpdate(originalClipboardText); } } } private static async Task WaitForClipboardToUpdate(string originalClipboardText) { Stopwatch sw = Stopwatch.StartNew(); while (true) { if (await DoClipboardCheck(originalClipboardText)) return; if (sw.ElapsedMilliseconds >= 1500) throw new Exception("TIMED OUT WAITING FOR CLIPBOARD TO UPDATE."); } } private static async Task<bool> DoClipboardCheck(string originalClipboardText) { await Task.Delay(10); if (!Clipboard.ContainsText()) return false; var currentText = Clipboard.GetText(); Debug.WriteLine("current text: " + currentText + " original text: " + originalClipboardText); return currentText != originalClipboardText; } [DllImport("user32.dll")] private static extern bool GetCursorPos(out Point pt); [DllImport("user32.dll", EntryPoint = "WindowFromPoint", CharSet = CharSet.Auto, ExactSpelling = true)] private static extern IntPtr WindowFromPoint(Point pt); // Activate an application window. [DllImport("USER32.DLL")] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImportAttribute("user32.dll", EntryPoint = "GetForegroundWindow")] public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
Also - a real quick and dirty way to quickly check / check if time is your problem, you can put Thread.Sleep (1000); after calls to SetForegroundWindow and SendKeys.SendWait.
kmcnamee
source share