2012-01-22 23 views
5

Duplicar posible:
SendInput and 64bitsSendInput falla en 64 bits

estoy usando SendInput de código .NET (PInvoke). El código
solía funcionar bien en el sistema operativo de 32 bits, pero ahora en WIN7 SendInput devuelve 0 y el último error se establece en 57 (ERROR_INVALID_PARAMETER).
No puedo compilar mi código como x86 ya que estoy cargado en un host de 64 bits. Además, probé varias soluciones con respecto a los tamaños de estructura y las compensaciones de campo, ninguna funcionó.
Estos son mis importaciones PInvoke y tipos:

[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); 

y el uso de código es:

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

donde los insumos matriz contiene 1 struct KEYBOARD_INPUT.
esto arroja un resultado = 0, y cuando reviso el último error, obtengo que el último error se establece en 57 (ERROR_INVALID_PARAMETER, el parámetro es incorrecto).

¿Hay alguna manera de hacer que esto funcione en el host de 64 bits en el sistema operativo WIN7 de 64 bits? esto funciona en XP ...

gracias

Respuesta

13

Trate de usar las siguientes definiciones (cortesía de 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); 

Luego, en su código de cliente, utilice:

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

Gran que resolvió el problema – Oren

Cuestiones relacionadas