问题描述
我正在尝试使用 PostMessage
向外部 32 位进程发送一些按键:
class WindowHook
{
const uint WM_KEYDOWN = 0x0100;
const uint WM_KEYUP = 0x101;
[DllImport("user32.dll",CharSet = CharSet.Auto,SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd,uint Msg,IntPtr wParam,IntPtr lParam);
[DllImport("user32.dll")]
private static extern short VkKeyScan(char ch);
[DllImport("user32.dll",CharSet = CharSet.Auto)]
private static extern uint MapVirtualKey(uint uCode,uint uMapType);
public static void SendKeystroke(char c,int processId)
{
var process = Process.GetProcessById(processId);
var hwdn = process.MainWindowHandle;
SendCharacter(c,hwdn);
}
private static void SendCharacter(char character,IntPtr hWnd)
{
var k = (uint)(int)ConvertCharToVirtualKey(character);
uint repeatCount = 1;
uint scanCode = MapVirtualKey(k,0);
uint extended = 0;
uint context = 0;
uint prevIoUsstate = 0;
uint transition = 0;
var lParamDown = repeatCount
| (scanCode << 16)
| (extended << 24)
| (context << 29)
| (prevIoUsstate << 30)
| (transition << 31);
prevIoUsstate = 1;
transition = 1;
var lParamUp = repeatCount
| (scanCode << 16)
| (extended << 24)
| (context << 29)
| (prevIoUsstate << 30)
| (transition << 31);
var ipKey = (IntPtr)(int)k;
var ipLParamDown = unchecked((IntPtr)(int)lParamDown);
var ipLParamUp = unchecked((IntPtr)(int)lParamUp);
PostMessage(hWnd,WM_KEYDOWN,ipKey,ipLParamDown);
var random = new Random().Next(50,100);
Thread.Sleep(random);
PostMessage(hWnd,WM_KEYUP,ipLParamUp);
}
private static Keys ConvertCharToVirtualKey(char ch)
{
var vkey = VkKeyScan(ch);
var retval = (Keys)(vkey & 0xff);
var modifiers = vkey >> 8;
if ((modifiers & 1) != 0) retval |= Keys.Shift;
if ((modifiers & 2) != 0) retval |= Keys.Control;
if ((modifiers & 4) != 0) retval |= Keys.Alt;
return retval;
}
}
这些消息与 spy++ 证明的实际按键生成的消息完全匹配,句柄是正确的,但消息没有被处理,或者他们什么也没做。
前 3 行是我的程序生成的,后 3 行是手动按键盘上的同一个键生成的。
我也尝试过 SendKeys.Send/Wait
,这些确实有效但不是很可靠,它们的点击也显示在 spy++ 的句柄消息中,但是如果每 10 毫秒发送一次消息,则只有大约 1 次被每 1000 毫秒处理一次,因此成功率约为 1/100。
对 PostMessage
的调用都返回 true,对 Marshal.GetLastWin32Error()
的调用返回 0。
我的程序在 64 位操作系统上运行,并设置了“首选 32 位”选项。目标软件年龄为20-25年,为32位进程。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)