2012-01-22 68 views
5

可能重複:
SendInput and 64bitsSendInput在64位失敗

我使用SendInput從.NET代碼(PInvoke的)。
代碼用於在32位操作系統上正常工作,但現在在WIN7上,SendInput返回0,並且最後的錯誤被設置爲57(ERROR_INVALID_PARAMETER)。
我無法將我的代碼編譯爲x86,因爲我將其加載到64位主機中。此外,我嘗試了各種關於結構尺寸和現場補償的解決方案,但都沒有成功。
這是我的PInvoke進口和類型:

[StructLayout(LayoutKind.Sequential)] 
struct KEYBOARD_INPUT 
{ 
    public uint type; 
    public ushort vk; 
    public ushort scanCode; 
    public uint flags; 
    public uint time; 
    public uint extrainfo; 
    public uint padding1; 
    public uint padding2; 
} 

[DllImport("User32.dll", SetLastError=true)] 
private static extern uint SendInput(
    uint numberOfInputs, 
    [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] KEYBOARD_INPUT[] input, 
    int structSize); 

和代碼的用法是:

uint result = SendInput(
     (uint)inputs.Count, 
     inputs.ToArray(), 
     Marshal.SizeOf(inputs[0])); 

其中輸入數組包含1層KEYBOARD_INPUT結構。
這產生的結果= 0,當我檢查最後一個錯誤時,我得到最後一個錯誤設置爲57(ERROR_INVALID_PARAMETER,該參數不正確)。

有沒有辦法在WIN7 64bit操作系統的64位主機下工作?這部作品在XP ...

感謝

回答

13

嘗試使用以下定義(的pinvoke.net提供):

const int INPUT_MOUSE = 0; 
const int INPUT_KEYBOARD = 1; 
const int INPUT_HARDWARE = 2; 
const uint KEYEVENTF_EXTENDEDKEY = 0x0001; 
const uint KEYEVENTF_KEYUP = 0x0002; 
const uint KEYEVENTF_UNICODE = 0x0004; 
const uint KEYEVENTF_SCANCODE = 0x0008; 

struct INPUT 
{ 
    public int type; 
    public InputUnion u; 
} 

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

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

[StructLayout(LayoutKind.Sequential)] 
struct KEYBDINPUT 
{ 
    /*Virtual Key code. Must be from 1-254. If the dwFlags member specifies KEYEVENTF_UNICODE, wVk must be 0.*/ 
    public ushort wVk; 
    /*A hardware scan code for the key. If dwFlags specifies KEYEVENTF_UNICODE, wScan specifies a Unicode character which is to be sent to the foreground application.*/ 
    public ushort wScan; 
    /*Specifies various aspects of a keystroke. See the KEYEVENTF_ constants for more information.*/ 
    public uint dwFlags; 
    /*The time stamp for the event, in milliseconds. If this parameter is zero, the system will provide its own time stamp.*/ 
    public uint time; 
    /*An additional value associated with the keystroke. Use the GetMessageExtraInfo function to obtain this information.*/ 
    public IntPtr dwExtraInfo; 
} 

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

[DllImport("user32.dll")] 
static extern IntPtr GetMessageExtraInfo(); 

[DllImport("user32.dll", SetLastError = true)] 
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); 

然後,在你的客戶端代碼,使用:

INPUT[] inputs = new INPUT[] 
{ 
    new INPUT 
    { 
     type = INPUT_KEYBOARD, 
     u = new InputUnion 
     { 
      ki = new KEYBDINPUT 
      { 
       wVk = key, 
       wScan = 0, 
       dwFlags = 0, 
       dwExtraInfo = GetMessageExtraInfo(), 
      } 
     } 
    } 
}; 

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

大,解決了這個問題 – Oren

相關問題