32 位进程接收消息但不执行消息

问题描述

我正在尝试使用 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++ 证明的实际按键生成的消息完全匹配,句柄是正确的,但消息没有被处理,或者他们什么也没做。

enter image description here

前 3 行是我的程序生成的,后 3 行是手动按键盘上的同一个生成的。

我也尝试过 SendKeys.Send/Wait,这些确实有效但不是很可靠,它们的点击也显示在 spy++ 的句柄消息中,但是如果每 10 毫秒发送一次消息,则只有大约 1 次被每 1000 毫秒处理一次,因此成功率约为 1/100。

PostMessage调用都返回 true,对 Marshal.GetLastWin32Error()调用返回 0。

我的程序在 64 位操作系统上运行,并设置了“首选 32 位”选项。目标软件年龄为20-25年,为32位进程。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)