C#并非正确地重播所有键盘事件

时间:2009-09-09 18:32:57

标签: c# automation keyboard mouse hook

我正在为验证工程师编写一个工具,以便在尝试重现故障时记录会话交互。它创建了一个桌面视频,我正在用C#挂钩键盘和鼠标,记录它们与操作系统的交互。 事件被序列化为稍后要读入的文件。 我使用SendInput重播鼠标和键盘事件。

除了重放剪切和粘贴交互之外,每件事都很有效。 CTRL-插入 SHIFT-插入

任何人都知道我做错了什么?

我的Hook代码:

   // if it's a keyboard event
{

   Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
   KeyEventArgs e = new KeyEventArgs(keyData);                    
   MyKeyEventArgs akea = new MyKeyEventArgs();
   akea.ExtraInfo = GetMessageExtraInfo();
   akea.Code = wParam;
   akea.KeyArgs = e;
   KeyDown(this, akea); // call to my event handler
}

我的SendInput代码

    // if it's a keyboard event
    {
     case KeyBoardHook.WM_KEYUP:
        tssKeyPress.Text = hec.KeyCode.ToString() + " Up";
        mi.mkhi.mi.dwExtraInfo = hec.ExtraInfo;
        k.mkhi.ki.dwFlags = KEYEVENTF_KEYUP;
        if (
            ((int)hec.KeyCode >= (int)VK.VK_PRIOR && (int)hec.KeyCode <= (int)VK.VK_DELETE) ||
            ((int)hec.KeyCode >= (int)VK.VK_LWIN && (int)hec.KeyCode <= (int)VK.VK_APPS) ||
            ((int)hec.KeyCode >= (int)VK.VK_SPACE && (int)hec.KeyCode <= (int)VK.VK_HELP) ||
            ((int)hec.KeyCode >= (int)VK.VK_SHIFT && (int)hec.KeyCode <= (int)VK.VK_MENU)
           )
        {
            k.mkhi.ki.dwFlags += KEYEVENTF_EXTENDEDKEY;
        }
        k.mkhi.ki.wVk = (ushort)hec.KeyCode;
        k.mkhi.ki.wScan = 0;
        //k.mkhi.mi.wScan = (short)hec.KeyData;
        k.mkhi.mi.time = 0;
        SendInput(1, ref k, Marshal.SizeOf(k));
        break;
    case KeyBoardHook.WM_KEYDOWN:
        tssKeyPress.Text = hec.KeyCode.ToString() + " Down";

        k.mkhi.ki.time = 0;
        k.mkhi.ki.dwExtraInfo = IntPtr.Zero;
        if (
            ((int)hec.KeyCode >= (int)VK.VK_PRIOR && (int)hec.KeyCode <= (int)VK.VK_DELETE ) ||
            ((int)hec.KeyCode >= (int)VK.VK_LWIN && (int)hec.KeyCode <= (int)VK.VK_APPS) ||
            ((int)hec.KeyCode >= (int)VK.VK_SPACE && (int)hec.KeyCode <= (int)VK.VK_HELP) ||
            ((int)hec.KeyCode >= (int)VK.VK_SHIFT && (int)hec.KeyCode <= (int)VK.VK_MENU)
           )
        {
            k.mkhi.ki.dwFlags += KEYEVENTF_EXTENDEDKEY;
        }
        k.mkhi.ki.dwFlags = 0;
        k.mkhi.ki.wVk = (ushort)hec.KeyCode;
        k.mkhi.ki.wScan = 0;
        //k.mkhi.mi.wScan = (short)hec.KeyData;
        SendInput(1, ref k, Marshal.SizeOf(k));
        break;
}

1 个答案:

答案 0 :(得分:1)

以下是重播键盘的工作方案:

case KeyBoardHook.WM_KEYUP:
    tssKeyPress.Text = hec.KeyCode.ToString() + " Up";
    k.mkhi.mi.dwExtraInfo = hec.ExtraInfo;
    k.mkhi.ki.dwFlags = KEYEVENTF_KEYUP;
    SetExtendedFlag( hec.KeyCode, ref k );
    k.mkhi.ki.wScan = 0;
    k.mkhi.mi.time = 0;
    SendInput(1, ref k, Marshal.SizeOf(k));
    break;
case KeyBoardHook.WM_KEYDOWN:
    tssKeyPress.Text = hec.KeyCode.ToString() + " Down";
    k.mkhi.mi.dwExtraInfo = hec.ExtraInfo;
    k.mkhi.ki.time = 0;
    k.mkhi.ki.dwFlags = 0;
    SetExtendedFlag( hec.KeyCode, ref k );
    k.mkhi.ki.wScan = 0;
    SendInput(1, ref k, Marshal.SizeOf(k));
    break;

private void SetExtendedFlag(Keys keys, ref INPUT k )
{
    k.mkhi.ki.wVk = (ushort)keys;
    if (((int)keys == (int)VK.VK_LSHIFT && (int)keys == (int)VK.VK_RSHIFT))
    {
        k.mkhi.ki.wVk = (ushort)VK.VK_SHIFT;
    }
    if (((int)keys == (int)VK.VK_LCONTROL && (int)keys == (int)VK.VK_RCONTROL))
    {
        k.mkhi.ki.wVk = (ushort)VK.VK_CONTROL;
    }
    if (((int)keys == (int)VK.VK_LMENU && (int)keys == (int)VK.VK_RMENU))
    {
        k.mkhi.ki.wVk = (ushort)VK.VK_MENU;
    }
    switch ((int)keys)
    {
        case((int) VK.VK_RMENU):
        case ((int)VK.VK_RCONTROL):                
        case ((int)VK.VK_INSERT):
        case ((int)VK.VK_DELETE):
        case ((int)VK.VK_LEFT):
        case ((int)VK.VK_HOME):
        case ((int)VK.VK_END):
        case ((int)VK.VK_UP):
        case ((int)VK.VK_DOWN):
        case ((int)VK.VK_PRIOR):
        case ((int)VK.VK_NEXT):
        case ((int)VK.VK_RIGHT):
        case ((int)VK.VK_LWIN):
        case ((int)VK.VK_RWIN):
        case ((int)VK.VK_APPS):
        case ((int)VK.VK_SLEEP):
            k.mkhi.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
            break;
    }
}

我现在可以使用CTRL-INSERT和SHIFT-INSERT成功重播复制,剪切和过去。