Send Keystrokes to a program even if its in backgr

2020-02-09 05:32发布

I wanna send key stroke to a program even if it is running in background. But I can do this only for NOTEPAD like this,

[DllImport("user32.dll")]
protected static extern byte VkKeyScan(char ch);

[DllImport("user32.dll", SetLastError = true)]
protected static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

[DllImport("User32.Dll", EntryPoint = "PostMessageA")]
protected static extern bool PostMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

char Key = // key value to send

IntPtr hWnd = FindWindowEx(_handle, IntPtr.Zero, "edit", null);   // _handle is the windows handle of the program (here its notepad)
PostMessage(hWnd, WM_KEYDOWN, VkKeyScan(Key), 0);

But for all other applications I can't send keystrokes if its in background. Since I don't know the lpszClass of that program (I think this is the userControl name of the typing area in that program. For NotePad it is "edit". I found this surfing internet).

For all other applications what I'm doing is, get the application to foreground, then send the key, then again get my program foreground. I need my program to be run as foreground always.

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

SetForegroundWindow(_handle);       // _handle is the windows handle of the program

System.Threading.Thread.Sleep(50);       // Waiting few milliseconds till application coming to foreground.                    
wsh.SendKeys(Key.ToString(), ref wait);  // wsh is WshShellClass wsh= new WshShellClass();
SetForegroundWindow(_mainHandle);    // _mainHandle is the windows handle of my application

But this way is not working. some keys getting missed and the program foreground->background->foregound->background...... like its dancing...

How to send keys to other applications if its running in background. or are there any way/source to find the lpszClass of a program ?

Sorry if I have missed any required information. this is a large application. I have posted only required parts here. If someone needs any additional information, pls ask.

2条回答
看我几分像从前
2楼-- · 2020-02-09 05:43

You may be able to figure out the lpszClass of the program using an inspection tool such as WinSpy++. It gives you a crosshair that you can drag and position over the desired control. This was able to easily provide me with the "edit" class name for notepad.

If things aren't working, click the "More>>" button in the lower right of WinSpy++, then click the "Locate" button to view the control hierarchy; you may need to post the WM_KEYDOWN message to one of the parent or child controls instead.

查看更多
Melony?
3楼-- · 2020-02-09 06:04

I think you'll need to have the background program install a low-level keyboard hook via the win32 function SetWindowsHookEx().

Here's the MSDN documentation for SetWindowsHookEX()

http://msdn.microsoft.com/en-us/library/ms644990(v=vs.85).aspx

And here's the KB article on how to do it from C#

http://support.microsoft.com/kb/318804

This article goes into some detail, too: http://www.codeguru.com/columns/vb/article.php/c4829

I expect your app will get caught by various spyware/anti-virus software as a keyboard logger, though.

Good luck.

查看更多
登录 后发表回答