2012-10-06 5 views
16

Ich verwende this board als eine Tastatur für Demozwecke.Senden Sie Schlüssel über SendInput in user32.dll

Wie auch immer, um die lange Geschichte kurz zu machen funktioniert alles gut, außer für sehr wenige Fälle. Ich sende Tastenanschläge mit der SendInput Funktion in user32.dll befindet.

So sieht mein Programm wie:

static void Main(string[] args) 
{ 
    Console.Write("Press enter an on the next secont the key combination shift+end will be send"); 
    Console.Read(); 

    Thread.Sleep(1000); 

    SendKeyDown(KeyCode.SHIFT); 
    SendKeyPress(KeyCode.END); 
    SendKeyUp(KeyCode.SHIFT); 

    Console.Read(); 
    Console.Read(); 
} 

[DllImport("user32.dll", SetLastError = true)] 
private static extern uint SendInput(uint numberOfInputs, INPUT[] inputs, int sizeOfInputStructure); 

/// <summary> 
/// simulate key press 
/// </summary> 
/// <param name="keyCode"></param> 
public static void SendKeyPress(KeyCode keyCode) 
{ 
    INPUT input = new INPUT { 
     Type = 1 
    }; 
    input.Data.Keyboard = new KEYBDINPUT() { 
     Vk = (ushort)keyCode, 
     Scan = 0, 
     Flags = 0, 
     Time = 0, 
     ExtraInfo = IntPtr.Zero, 
    }; 

    INPUT input2 = new INPUT { 
     Type = 1 
    }; 
    input2.Data.Keyboard = new KEYBDINPUT() { 
     Vk = (ushort)keyCode, 
     Scan = 0, 
     Flags = 2, 
     Time = 0, 
     ExtraInfo = IntPtr.Zero 
    }; 
    INPUT[] inputs = new INPUT[] { input, input2 }; 
    if (SendInput(2, inputs, Marshal.SizeOf(typeof(INPUT))) == 0) 
     throw new Exception();    
} 

/// <summary> 
/// Send a key down and hold it down until sendkeyup method is called 
/// </summary> 
/// <param name="keyCode"></param> 
public static void SendKeyDown(KeyCode keyCode) 
{ 
    INPUT input = new INPUT{ 
     Type = 1 
    }; 
    input.Data.Keyboard = new KEYBDINPUT(); 
    input.Data.Keyboard.Vk = (ushort)keyCode; 
    input.Data.Keyboard.Scan = 0; 
    input.Data.Keyboard.Flags = 0; 
    input.Data.Keyboard.Time = 0; 
    input.Data.Keyboard.ExtraInfo = IntPtr.Zero; 
    INPUT[] inputs = new INPUT[] { input }; 
    if (SendInput(1, inputs, Marshal.SizeOf(typeof(INPUT))) == 0) 
    { 
     throw new Exception(); 
    } 
} 

/// <summary> 
/// Release a key that is being hold down 
/// </summary> 
/// <param name="keyCode"></param> 
public static void SendKeyUp(KeyCode keyCode) 
{ 
    INPUT input = new INPUT { 
     Type = 1 
    }; 
    input.Data.Keyboard = new KEYBDINPUT(); 
    input.Data.Keyboard.Vk = (ushort)keyCode; 
    input.Data.Keyboard.Scan = 0; 
    input.Data.Keyboard.Flags = 2; 
    input.Data.Keyboard.Time = 0; 
    input.Data.Keyboard.ExtraInfo = IntPtr.Zero; 
    INPUT[] inputs = new INPUT[] { input }; 
    if (SendInput(1, inputs, Marshal.SizeOf(typeof(INPUT))) == 0) 
     throw new Exception(); 

} 

Und hier sind die Strukturen sind, die ich online gefunden, dass diese Methoden verwenden, und auch die Tastencodes: (beachten Sie es wie eine Menge Code aussieht und weil es viele Schlüsselcodes sind in einer Enum)

/// <summary> 
    /// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx 
    /// </summary> 
    [StructLayout(LayoutKind.Sequential)] 
    internal struct INPUT 
    { 
     public uint Type; 
     public MOUSEKEYBDHARDWAREINPUT Data; 
    } 

    /// <summary> 
    /// http://social.msdn.microsoft.com/Forums/en/csharplanguage/thread/f0e82d6e-4999-4d22-b3d3-32b25f61fb2a 
    /// </summary> 
    [StructLayout(LayoutKind.Explicit)] 
    internal struct MOUSEKEYBDHARDWAREINPUT 
    { 
     [FieldOffset(0)] 
     public HARDWAREINPUT Hardware; 
     [FieldOffset(0)] 
     public KEYBDINPUT Keyboard; 
     [FieldOffset(0)] 
     public MOUSEINPUT Mouse; 
    } 

    /// <summary> 
    /// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx 
    /// </summary> 
    [StructLayout(LayoutKind.Sequential)] 
    internal struct HARDWAREINPUT 
    { 
     public uint Msg; 
     public ushort ParamL; 
     public ushort ParamH; 
    } 

    /// <summary> 
    /// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx 
    /// </summary> 
    [StructLayout(LayoutKind.Sequential)] 
    internal struct KEYBDINPUT 
    { 
     public ushort Vk; 
     public ushort Scan; 
     public uint Flags; 
     public uint Time; 
     public IntPtr ExtraInfo; 
    } 

    /// <summary> 
    /// http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/2abc6be8-c593-4686-93d2-89785232dacd 
    /// </summary> 
    [StructLayout(LayoutKind.Sequential)] 
    internal struct MOUSEINPUT 
    { 
     public int X; 
     public int Y; 
     public uint MouseData; 
     public uint Flags; 
     public uint Time; 
     public IntPtr ExtraInfo; 
    } 

    public enum KeyCode : ushort 
    { 
     #region Media 

     /// <summary> 
     /// Next track if a song is playing 
     /// </summary> 
     MEDIA_NEXT_TRACK = 0xb0, 

     /// <summary> 
     /// Play pause 
     /// </summary> 
     MEDIA_PLAY_PAUSE = 0xb3, 

     /// <summary> 
     /// Previous track 
     /// </summary> 
     MEDIA_PREV_TRACK = 0xb1, 

     /// <summary> 
     /// Stop 
     /// </summary> 
     MEDIA_STOP = 0xb2, 

     #endregion 

     #region math 

     /// <summary>Key "+"</summary> 
     ADD = 0x6b, 
     /// <summary> 
     /// "*" key 
     /// </summary> 
     MULTIPLY = 0x6a, 

     /// <summary> 
     /// "/" key 
     /// </summary> 
     DIVIDE = 0x6f, 

     /// <summary> 
     /// Subtract key "-" 
     /// </summary> 
     SUBTRACT = 0x6d, 

     #endregion 

     #region Browser 
     /// <summary> 
     /// Go Back 
     /// </summary> 
     BROWSER_BACK = 0xa6, 
     /// <summary> 
     /// Favorites 
     /// </summary> 
     BROWSER_FAVORITES = 0xab, 
     /// <summary> 
     /// Forward 
     /// </summary> 
     BROWSER_FORWARD = 0xa7, 
     /// <summary> 
     /// Home 
     /// </summary> 
     BROWSER_HOME = 0xac, 
     /// <summary> 
     /// Refresh 
     /// </summary> 
     BROWSER_REFRESH = 0xa8, 
     /// <summary> 
     /// browser search 
     /// </summary> 
     BROWSER_SEARCH = 170, 
     /// <summary> 
     /// Stop 
     /// </summary> 
     BROWSER_STOP = 0xa9, 
     #endregion 

     #region Numpad numbers 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD0 = 0x60, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD1 = 0x61, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD2 = 0x62, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD3 = 0x63, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD4 = 100, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD5 = 0x65, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD6 = 0x66, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD7 = 0x67, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD8 = 0x68, 
     /// <summary> 
     /// 
     /// </summary> 
     NUMPAD9 = 0x69, 

     #endregion 

     #region Fkeys 
     /// <summary> 
     /// F1 
     /// </summary> 
     F1 = 0x70, 
     /// <summary> 
     /// F10 
     /// </summary> 
     F10 = 0x79, 
     /// <summary> 
     /// 
     /// </summary> 
     F11 = 0x7a, 
     /// <summary> 
     /// 
     /// </summary> 
     F12 = 0x7b, 
     /// <summary> 
     /// 
     /// </summary> 
     F13 = 0x7c, 
     /// <summary> 
     /// 
     /// </summary> 
     F14 = 0x7d, 
     /// <summary> 
     /// 
     /// </summary> 
     F15 = 0x7e, 
     /// <summary> 
     /// 
     /// </summary> 
     F16 = 0x7f, 
     /// <summary> 
     /// 
     /// </summary> 
     F17 = 0x80, 
     /// <summary> 
     /// 
     /// </summary> 
     F18 = 0x81, 
     /// <summary> 
     /// 
     /// </summary> 
     F19 = 130, 
     /// <summary> 
     /// 
     /// </summary> 
     F2 = 0x71, 
     /// <summary> 
     /// 
     /// </summary> 
     F20 = 0x83, 
     /// <summary> 
     /// 
     /// </summary> 
     F21 = 0x84, 
     /// <summary> 
     /// 
     /// </summary> 
     F22 = 0x85, 
     /// <summary> 
     /// 
     /// </summary> 
     F23 = 0x86, 
     /// <summary> 
     /// 
     /// </summary> 
     F24 = 0x87, 
     /// <summary> 
     /// 
     /// </summary> 
     F3 = 0x72, 
     /// <summary> 
     /// 
     /// </summary> 
     F4 = 0x73, 
     /// <summary> 
     /// 
     /// </summary> 
     F5 = 0x74, 
     /// <summary> 
     /// 
     /// </summary> 
     F6 = 0x75, 
     /// <summary> 
     /// 
     /// </summary> 
     F7 = 0x76, 
     /// <summary> 
     /// 
     /// </summary> 
     F8 = 0x77, 
     /// <summary> 
     /// 
     /// </summary> 
     F9 = 120, 

     #endregion 

     #region Other 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_1 = 0xba, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_102 = 0xe2, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_2 = 0xbf, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_3 = 0xc0, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_4 = 0xdb, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_5 = 220, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_6 = 0xdd, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_7 = 0xde, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_8 = 0xdf, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_CLEAR = 0xfe, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_COMMA = 0xbc, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_MINUS = 0xbd, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_PERIOD = 190, 
     /// <summary> 
     /// 
     /// </summary> 
     OEM_PLUS = 0xbb, 

     #endregion 

     #region KEYS 

     /// <summary> 
     /// 
     /// </summary> 
     KEY_0 = 0x30, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_1 = 0x31, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_2 = 50, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_3 = 0x33, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_4 = 0x34, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_5 = 0x35, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_6 = 0x36, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_7 = 0x37, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_8 = 0x38, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_9 = 0x39, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_A = 0x41, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_B = 0x42, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_C = 0x43, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_D = 0x44, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_E = 0x45, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_F = 70, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_G = 0x47, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_H = 0x48, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_I = 0x49, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_J = 0x4a, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_K = 0x4b, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_L = 0x4c, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_M = 0x4d, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_N = 0x4e, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_O = 0x4f, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_P = 80, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_Q = 0x51, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_R = 0x52, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_S = 0x53, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_T = 0x54, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_U = 0x55, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_V = 0x56, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_W = 0x57, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_X = 0x58, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_Y = 0x59, 
     /// <summary> 
     /// 
     /// </summary> 
     KEY_Z = 90, 

     #endregion 

     #region volume 
     /// <summary> 
     /// Decrese volume 
     /// </summary> 
     VOLUME_DOWN = 0xae, 

     /// <summary> 
     /// Mute volume 
     /// </summary> 
     VOLUME_MUTE = 0xad, 

     /// <summary> 
     /// Increase volue 
     /// </summary> 
     VOLUME_UP = 0xaf, 

     #endregion 


     /// <summary> 
     /// Take snapshot of the screen and place it on the clipboard 
     /// </summary> 
     SNAPSHOT = 0x2c, 

     /// <summary>Send right click from keyboard "key that is 2 keys to the right of space bar"</summary> 
     RightClick = 0x5d, 

     /// <summary> 
     /// Go Back or delete 
     /// </summary> 
     BACKSPACE = 8, 

     /// <summary> 
     /// Control + Break "When debuging if you step into an infinite loop this will stop debug" 
     /// </summary> 
     CANCEL = 3, 
     /// <summary> 
     /// Caps lock key to send cappital letters 
     /// </summary> 
     CAPS_LOCK = 20, 
     /// <summary> 
     /// Ctlr key 
     /// </summary> 
     CONTROL = 0x11, 

     /// <summary> 
     /// Alt key 
     /// </summary> 
     ALT = 18, 

     /// <summary> 
     /// "." key 
     /// </summary> 
     DECIMAL = 110, 

     /// <summary> 
     /// Delete Key 
     /// </summary> 
     DELETE = 0x2e, 


     /// <summary> 
     /// Arrow down key 
     /// </summary> 
     DOWN = 40, 

     /// <summary> 
     /// End key 
     /// </summary> 
     END = 0x23, 

     /// <summary> 
     /// Escape key 
     /// </summary> 
     ESC = 0x1b, 

     /// <summary> 
     /// Home key 
     /// </summary> 
     HOME = 0x24, 

     /// <summary> 
     /// Insert key 
     /// </summary> 
     INSERT = 0x2d, 

     /// <summary> 
     /// Open my computer 
     /// </summary> 
     LAUNCH_APP1 = 0xb6, 
     /// <summary> 
     /// Open calculator 
     /// </summary> 
     LAUNCH_APP2 = 0xb7, 

     /// <summary> 
     /// Open default email in my case outlook 
     /// </summary> 
     LAUNCH_MAIL = 180, 

     /// <summary> 
     /// Opend default media player (itunes, winmediaplayer, etc) 
     /// </summary> 
     LAUNCH_MEDIA_SELECT = 0xb5, 

     /// <summary> 
     /// Left control 
     /// </summary> 
     LCONTROL = 0xa2, 

     /// <summary> 
     /// Left arrow 
     /// </summary> 
     LEFT = 0x25, 

     /// <summary> 
     /// Left shift 
     /// </summary> 
     LSHIFT = 160, 

     /// <summary> 
     /// left windows key 
     /// </summary> 
     LWIN = 0x5b, 


     /// <summary> 
     /// Next "page down" 
     /// </summary> 
     PAGEDOWN = 0x22, 

     /// <summary> 
     /// Num lock to enable typing numbers 
     /// </summary> 
     NUMLOCK = 0x90, 

     /// <summary> 
     /// Page up key 
     /// </summary> 
     PAGE_UP = 0x21, 

     /// <summary> 
     /// Right control 
     /// </summary> 
     RCONTROL = 0xa3, 

     /// <summary> 
     /// Return key 
     /// </summary> 
     ENTER = 13, 

     /// <summary> 
     /// Right arrow key 
     /// </summary> 
     RIGHT = 0x27, 

     /// <summary> 
     /// Right shift 
     /// </summary> 
     RSHIFT = 0xa1, 

     /// <summary> 
     /// Right windows key 
     /// </summary> 
     RWIN = 0x5c, 

     /// <summary> 
     /// Shift key 
     /// </summary> 
     SHIFT = 0x10, 

     /// <summary> 
     /// Space back key 
     /// </summary> 
     SPACE_BAR = 0x20, 

     /// <summary> 
     /// Tab key 
     /// </summary> 
     TAB = 9, 

     /// <summary> 
     /// Up arrow key 
     /// </summary> 
     UP = 0x26, 

    } 

so jetzt meine Frage ist, warum, wenn ich sende diese Tastenkombination ich nicht die gleichen Ergebnisse wie, wenn ich es auf einem echten ke tun yboard? 98% der Dinge funktionieren. Zum Beispiel bin ich in der Lage zu tun:

SendKeyDown(KeyCode.SHIFT); 
    SendKeyPress(KeyCode.KEY_A); 
    SendKeyUp(KeyCode.SHIFT); 

Und das wird ein Kapital A.

Soll ich eine andere Bibliothek verwenden schicken?

Der Grund, warum ich diesen Ansatz mag, ist, weil ich nicht im Voraus wissen, ob der Benutzer eine Tastenkombination Zum Beispiel in Windows Forms senden Wenn wir tun:

System.Windows.Forms.SendKeys.SendWait("+{end}"); die Shift + Ende senden wird aber Vielleicht möchte der Benutzer nur die Schicht senden ...

Antwort

10

Sie setzen die Flags und Scanfelder nicht, abhängig von den gewünschten Tastenanschlägen, müssen Sie diese richtig einstellen, damit das Betriebssystem die Tasten richtig erkennt.

Sie könnten die Bibliothek Input Simulator in Erwägung ziehen, da sie bereits das tut, was Sie wollen, und Sie das Rad nicht neu erstellen müssen. Schaue einfach durch die Foren, da es dort einige gute Patches gibt, die gesetzt werden müssen, da der Autor das Projekt 2009 aufgegeben hat. Trotzdem ist es eine gute Bibliothek.

+1

DANKE diese ist was ich gesucht habe! – hurnhu

0

Eine weitere Möglichkeit, Tastatureingaben an ein Fenster senden (ich benutze diese Tests für UI), um die Unicode-Alternative in KEYBDINPUT zu verwenden ist, die Sie speichert jedes Zeichen in den virtuellen Schlüssel aus Abbildung:

public static void SendString(string inputStr) 
{ 
    var hWnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle; 
    WinAPI.SetForegroundWindow(hWnd);   
    List<WinAPI.INPUT> keyList = new List<WinAPI.INPUT>(); 
    foreach (short c in inputStr) 
    { 
     switch (c) 
     { 
      case 8: // Translate \t to VK_TAB 
       { 
        WinAPI.INPUT keyDown = new WinAPI.INPUT(); 
        keyDown.type = 1; //Keyboard 
        keyDown.union.keyboardInput.wVk = (short)WinAPI.WindowsVirtualKey.VK_TAB; 
        keyDown.union.keyboardInput.dwFlags = 0; 
        keyDown.union.keyboardInput.wScan = 0; //use VirtualKey 
        keyList.Add(keyDown); 
        WinAPI.INPUT keyUp = new WinAPI.INPUT(); 
        keyUp.type = 1; //Keyboard 
        keyUp.union.keyboardInput.wVk = (short)WinAPI.WindowsVirtualKey.VK_TAB; 
        keyUp.union.keyboardInput.dwFlags = 0x0002; 
        keyUp.union.keyboardInput.wScan = 0; //use VirtualKey 
        keyList.Add(keyUp); 
       } 
       break; 
      case 10: // Translate \n to VK_RETURN 
       { 
        WinAPI.INPUT keyDown = new WinAPI.INPUT(); 
        keyDown.type = 1; //Keyboard 
        keyDown.union.keyboardInput.wVk = (short)WinAPI.WindowsVirtualKey.VK_RETURN; 
        keyDown.union.keyboardInput.dwFlags = 0; 
        keyDown.union.keyboardInput.wScan = 0; //use VirtualKey 
        keyList.Add(keyDown); 
        WinAPI.INPUT keyUp = new WinAPI.INPUT(); 
        keyUp.type = 1; //Keyboard 
        keyUp.union.keyboardInput.wVk = (short)WinAPI.WindowsVirtualKey.VK_RETURN; 
        keyUp.union.keyboardInput.dwFlags = 0x0002; 
        keyUp.union.keyboardInput.wScan = 0; //use VirtualKey 
        keyList.Add(keyUp); 
       } 
       break;     
      default: 
       { 
        WinAPI.INPUT keyDown = new WinAPI.INPUT(); 
        keyDown.type = 1; //Keyboard 
        keyDown.union.keyboardInput.wVk = 0; //Use unicode 
        keyDown.union.keyboardInput.dwFlags = 0x0004; //Unicode Key Down 
        keyDown.union.keyboardInput.wScan = c; 
        keyList.Add(keyDown); 
        WinAPI.INPUT keyUp = new WinAPI.INPUT(); 
        keyUp.type = 1; //Keyboard 
        keyUp.union.keyboardInput.wVk = 0; //Use unicode 
        keyUp.union.keyboardInput.dwFlags = 0x0004 | 0x0002; //Unicode Key Up 
        keyUp.union.keyboardInput.wScan = c; 
        keyList.Add(keyUp); 
       } 
       break; 
     } 
    } 
    WinAPI.SendInput((uint)keyList.Count, keyList.ToArray(), Marshal.SizeOf(typeof(WinAPI.INPUT)));    
} 
Verwandte Themen