2009-09-09 7 views
0

Je suis en train d'écrire un outil permettant aux ingénieurs de validation de consigner les interactions de session lorsque vous tentez de reproduire une erreur. Il crée une vidéo du bureau, et je suis en train d'accrocher le clavier et la souris en C#, pour enregistrer leur interaction avec le système d'exploitation. Les événements sont sérialisés sur un fichier à lire ultérieurement. J'utilise SendInput pour relire les événements de la souris et du clavier. Tout fonctionne très bien, sauf la relecture des interactions copier-coller. CTRL-Insert SHIFT-InsertC# Tous les événements de clavier ne sont pas rejoués correctement

Quelqu'un sait ce que je fais mal?

Mon code 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 
} 

Code Mon 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; 
} 
+0

Etes-vous sûr de dwFlags + = KEYEVENTF_EXTENDEDKEY? Il me semble que vous voulez dire '=' ou '| ='. En outre, l'instruction if dans le cas KEYDOWN est dénuée de sens, car l'instruction suivante écrase immédiatement la valeur dwFlags avec 0. – JeffH

+1

DOH! vous avez raison dans les deux cas. J'ai réparé ça, mais toujours pas de dés. Mais je l'ai résolu. J'ai ajouté une fonction à | = le KEYEVENTF_EXTENDEDKEY basé sur les informations trouvées dans cet article: http://msdn.microsoft.com/en-us/library/ms646304(VS.85).aspx J'ai également modifié le code pour convertir VK_LSHIFT et VK_RSHIFT à VK_SHIFT, VK_LCONTROL et VK_RCONTROL à VK_CONTROL, et VK_LMENU et VK_RMENU à VK_MENU. Je suis maintenant capable de couper et coller. Tout est bon! Merci –

Répondre

1

Voici ma solution de travail pour rejouer le clavier:

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; 
    } 
} 

je peux copier maintenant rejouer avec succès, et couper et passer en utilisant CTRL-INSERT, et SHIFT-INSERT.

Questions connexes