2014-12-03 92 views
0

我正在使用下面的代碼來傳遞使用SendInput的特殊鍵。我面臨着一個奇怪的問題。如果用戶發送任何Alt/Ctrl/Shift,按鍵保持按下,例如,如果用戶通過Alt + F4,代碼正常運行並且操作成功完成,但Alt鍵保持按下狀態。操作完成後,我需要手動點擊Alt鍵。請讓我知道在代碼本身中處理相同的內容。以下是用於發送特殊密鑰的代碼。C#SendInput Alt/Ctrl/Shift鍵未獲得發佈

namespace RemoteDesktopSendKeys 
{ 
class Program 
{ 
     struct INPUT 
    { 
     public INPUTType type; 
     public INPUTUnion Event; 
    } 

    [StructLayout(LayoutKind.Explicit)] 
    struct INPUTUnion 
    { 
     [FieldOffset(0)] 
     internal MOUSEINPUT mi; 
     [FieldOffset(0)] 
     internal KEYBDINPUT ki; 
     [FieldOffset(0)] 
     internal HARDWAREINPUT hi; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct MOUSEINPUT 
    { 
     public int dx; 
     public int dy; 
     public int mouseData; 
     public int dwFlags; 
     public uint time; 
     public IntPtr dwExtraInfo; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct KEYBDINPUT 
    { 
     public ushort wVk; 
     public ushort wScan; 
     public KEYEVENTF dwFlags; 
     public int time; 
     public IntPtr dwExtraInfo; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    struct HARDWAREINPUT 
    { 
     public int uMsg; 
     public short wParamL; 
     public short wParamH; 
    } 

    enum INPUTType : uint 
    { 
     INPUT_KEYBOARD = 1 
    } 

    [Flags] 
    enum KEYEVENTF : uint 
    { 
     EXTENDEDKEY = 0x0001, 
     KEYUP = 0x0002, 
     SCANCODE = 0x0008, 
     UNICODE = 0x0004 
    } 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern UInt32 SendInput(int numberOfInputs, INPUT[] inputs, int sizeOfInputStructure); 
    [DllImport("user32.dll")] 
    public static extern IntPtr GetMessageExtraInfo(); 
    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    internal static extern uint MapVirtualKey(uint uCode, uint uMapType); 
    private const int KEYEVENTF_KEYUP1 = 0x0002; 

    [DllImport("user32.dll")] 
    static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo); 

    [DllImport("user32.dll", CharSet = CharSet.Auto)] 
    internal static extern int MapVirtualKey(int uCode, int uMapType); 


    static void Main(string[] args) 
    { 
     Thread.Sleep(3000); 
      int[] keyboardStrokes = { (int)Keys.LMenu,(int)Keys.F4 }; 

     //int[] keyboardStrokes = { (int)Keys.ControlKey, (int)Keys.A }; 


     SendSpecialKeys("test", keyboardStrokes); 

     //SendSpecialKeys("F5",keyboardStrokes); 
    } 

    private static void SendSpecialKeys(string text, int[] modifiers) 
    { 

     List<int> arrKeys = new List<int>(); 
     Keys key; 

     if (modifiers != null && modifiers.Length > 0) 
     { 
      for (int i = 0; i < modifiers.Length; i++) 
      { 
       arrKeys.Add(modifiers[i]); 
      } 
     } 

     if (!string.IsNullOrEmpty(text)) 
     { 
      if (Enum.TryParse(text, out key)) 
       arrKeys.Add((int)key); 
      else 
       SendText(text); 
     } 

     System.Threading.Thread.Sleep(1000); 
     int[] arrKeyStrokes = arrKeys.ToArray(); 
     INPUT[] inputs = new INPUT[arrKeyStrokes.Length + 1]; 

     for (int i = 0; i < arrKeyStrokes.Length; i++) 
     { 
      uint skey = MapVirtualKey((uint)arrKeyStrokes[i], (uint)0x0); 
      inputs[i].type = INPUTType.INPUT_KEYBOARD; 
      inputs[i].Event.ki.dwFlags = KEYEVENTF.SCANCODE; 
      inputs[i].Event.ki.wScan = (ushort)skey; 
     } 

     inputs[arrKeyStrokes.Length].type = INPUTType.INPUT_KEYBOARD; 
     inputs[arrKeyStrokes.Length].Event.ki.dwFlags = KEYEVENTF.SCANCODE; 
     inputs[arrKeyStrokes.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP; 

     SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT))); 

    } 
    public static void SendText(string text) 
    { 
     List<INPUT> kbInput = new List<INPUT>(); 

     foreach (char c in text) 
     { 
      // Send a key down followed by key up. 
      foreach (bool keyUp in new bool[] { false, true }) 
      { 
       INPUT input = new INPUT 
       { 
        type = INPUTType.INPUT_KEYBOARD, 
        Event = new INPUTUnion 
        { 
         // This will contain keyboard event information 
         ki = new KEYBDINPUT 
         { 
          wVk = 0, 
          wScan = c, 
          dwFlags = KEYEVENTF.UNICODE | (keyUp ? KEYEVENTF.KEYUP : 0), 
          dwExtraInfo = GetMessageExtraInfo(), 
         } 
        } 
       }; 

       kbInput.Add(input); 
      } 
     } 

     // Call SendInputWindows API to send input 
     SendInput((int)kbInput.Count, kbInput.ToArray(), Marshal.SizeOf(typeof(INPUT))); 
    } 
} 

}

+0

它只是錯誤的代碼。你不要設置Event.ki.wScan作爲輸入[arrKeyStrokes.Length],你只能生成*一個* KEYUP。 – 2014-12-03 18:04:52

回答

0

下面的代碼可以被用來釋放特定密鑰。以下是釋放控制鍵的示例代碼。

uint ctrlkey = MapVirtualKey((uint)Keys.ControlKey, (uint)0x0); 
       inputs[index].type = INPUTType.INPUT_KEYBOARD; 
       inputs[index].Event.ki.dwFlags = KEYEVENTF.SCANCODE; 
       inputs[index].Event.ki.dwFlags |= KEYEVENTF.KEYUP; 
       inputs[index].Event.ki.wScan = (ushort)ctrlkey; 

需要確保,適當的密鑰被正確地傳遞指數發佈。