Send win api paste cmd from c # background application

Purpose : to write a C # application that runs in the background, listens for a Win-V key combination, and when this happens, paste the contents of the clipboard into the currently active window (some arbitrary application), In fact, I'm trying to imitate PureText , but I do not want to convert the text to plain text first.

Problem : pasting into active windows does not work.

Details To listen in the background for keystrokes, I use the globalKeyboardHook class from Simple C # Global Low Level Keyboard Hook.I can catch Win-V events, but I can not send the insert command correctly. I can send the paste using the SendKeys.Send or keybd_event functions . However, they send another ā€œVā€ message down the pipeline that hits the gkh_KeyDown event and raises multiple merge events.

I expect that I need to use SendMessage or PostMessage , but all my attempts to do this have failed. Below is the complete code with the latest SendCtrlV function of interest. Comments explain everything I have tried so far. Do you see what I am missing?

using System; using System.IO; using System.Runtime.InteropServices; using System.Windows.Forms; using Utilities; namespace KeyHookTest { public partial class Form1 : Form { private bool LWin_down; private bool V_down; globalKeyboardHook gkh = new globalKeyboardHook(); [DllImport("user32.dll", CharSet = CharSet.Auto)] static public extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); [DllImport("user32.dll")] private static extern int SendMessage(IntPtr hwnd, int msg, int wParam, int lParam); [DllImport("user32.dll")] public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { gkh.HookedKeys.Add(Keys.V); gkh.HookedKeys.Add(Keys.LWin); gkh.KeyDown += new KeyEventHandler(gkh_KeyDown); gkh.KeyUp += new KeyEventHandler(gkh_KeyUp); } void gkh_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.LWin) LWin_down = false; else V_down = false; } void gkh_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.LWin) LWin_down = true; else V_down = true; if (LWin_down && V_down) { LogDebug("Enter Win+V"); try { SendCtrlV(); } catch { } } } private void SendCtrlV() { uint KEYEVENTF_KEYUP = 2; int KEYDOWN = 0x0100; int KEYUP = 0x0101; byte KEY_LCONTROL1 = 0x11; IntPtr KEY_LCONTROL2 = new IntPtr(0x11); byte KEY_V1 = 0x56; IntPtr KEY_V2 = new IntPtr(0x56); int WM_PASTE1 = 0x302; uint WM_PASTE2 = 0x302; IntPtr hWnd = GetForegroundWindow(); // Works, but causes multiple gkh_KeyDown to fire so it slow and buggy /*keybd_event(KEY_LCONTROL1, 0, 0, 0); keybd_event(KEY_V1, 0, 0, 0); keybd_event(KEY_V1, 0, KEYEVENTF_KEYUP, 0); keybd_event(KEY_LCONTROL1, 0, KEYEVENTF_KEYUP, 0);*/ // Works, but causes multiple gkh_KeyDown to fire so it slow and buggy //SendKeys.Send("^v"); // Doesn't work, causes UAC prompt //SendKeys.Send("{^}v"); // Doesn't work, nothing gets pasted to the foregroundwindow //SendMessage(hWnd, WM_PASTE1, 0, 0); // Doesn't work, nothing gets pasted to the foregroundwindow //PostMessage(hWnd, WM_PASTE2, IntPtr.Zero, IntPtr.Zero); // Doesn't work, nothing gets pasted to the foregroundwindow /*SendMessage(hWnd, KEYDOWN, KEY_LCONTROL1, 0); SendMessage(hWnd, KEYDOWN, KEY_V1, 0); SendMessage(hWnd, KEYUP, KEY_V1, 0); SendMessage(hWnd, KEYUP, KEY_LCONTROL1, 0);*/ // Doesn't work, nothing gets pasted to the foregroundwindow /*PostMessage(hWnd, 0x0100, KEY_LCONTROL2, IntPtr.Zero); PostMessage(hWnd, 0x0100, KEY_V2, IntPtr.Zero); PostMessage(hWnd, 0x0101, KEY_V2, IntPtr.Zero); PostMessage(hWnd, 0x0101, KEY_LCONTROL2, IntPtr.Zero);*/ } private void LogDebug(string msg) { string logpath = Environment.GetEnvironmentVariable("USERPROFILE") + @"\Desktop\KeyHookTest.txt"; File.AppendAllText(logpath, DateTime.Now.ToString("HH:mm:ss:fff") + ": " + msg + "\r\n"); } } } 
+6
source share
1 answer

These sitelinks helped me answer:

Here is what works for me:

 private void SendCtrlV() { IntPtr hWnd = GetFocusedHandle(); PostMessage(hWnd, WM_PASTE, IntPtr.Zero, IntPtr.Zero); } static IntPtr GetFocusedHandle() { var info = new GuiThreadInfo(); info.cbSize = Marshal.SizeOf(info); if (!GetGUIThreadInfo(0, ref info)) throw new Win32Exception(); return info.hwndFocus; } 
+1
source

Source: https://habr.com/ru/post/923602/


All Articles