.net 发送输入和64位
下面是我用来通过SendInputAPI模拟按键的一些代码的摘录。如果我将我的应用程序设置为针对x86 CPU编译,但不适用于x64 CPU编译,则此功能正常工作 我猜这与x64使用双尺寸指针这一事实有关,但我尝试将此.net 发送输入和64位,.net,pinvoke,64-bit,sendinput,.net,Pinvoke,64 Bit,Sendinput,下面是我用来通过SendInputAPI模拟按键的一些代码的摘录。如果我将我的应用程序设置为针对x86 CPU编译,但不适用于x64 CPU编译,则此功能正常工作 我猜这与x64使用双尺寸指针这一事实有关,但我尝试将此[FieldOffset(4)]更改为此[FieldOffset(8)],但它不起作用 这可能与它正在导入32位版本的user32.dll有关吗 #region SendInput API [DllImport("user32.dll", EntryPoint =
[FieldOffset(4)]
更改为此[FieldOffset(8)]
,但它不起作用
这可能与它正在导入32位版本的user32.dll有关吗
#region SendInput API
[DllImport("user32.dll", EntryPoint = "SendInput", SetLastError = true)]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
[DllImport("user32.dll", EntryPoint = "GetMessageExtraInfo", SetLastError = true)]
static extern IntPtr GetMessageExtraInfo();
private enum KeyEvent
{
KeyUp = 0x0002,
KeyDown = 0x0000,
ExtendedKey = 0x0001
}
private struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public long time;
public uint dwExtraInfo;
};
[StructLayout(LayoutKind.Explicit, Size = 28)]
private struct INPUT
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public KEYBDINPUT ki;
};
#endregion
public void sendKey(KeyCode Key)
{
INPUT[] InputList = new INPUT[2];
INPUT keyInput = new INPUT();
keyInput.type = 1;
keyInput.ki.wScan = 0;
keyInput.ki.time = 0;
keyInput.ki.dwFlags = (int)KeyEvent.KeyDown;
keyInput.ki.dwExtraInfo = (uint)GetMessageExtraInfo();
keyInput.ki.wVk = (ushort)Key;
InputList[0] = keyInput;
keyInput.ki.dwFlags = (int)KeyEvent.KeyUp;
InputList[1] = keyInput;
SendInput((uint)2, InputList, Marshal.SizeOf(InputList[0]));
}
dwExtraInfo
是一个指针。因此,在32位代码中需要4字节宽,在64位代码中需要8字节宽
要在C#中执行此操作,请使用
IntPtr
(而不是uint
,它始终为4个字节)除了SLaks识别的错误之外,您的剩余问题是输入的大小不正确。这意味着SendInput
失败,因为它接收到类型为INPUT[]
的参数。无法使用StructLayout(LayoutKind.Explicit,size=28)
指定大小,因为您需要同时处理x86和x64的代码
这一切都源于这样一个事实,即您只在INPUT
中包含了KEYBRDINPUT
结构。MOUSEINPUT
struct大于KEYBRDINPUT
,这是问题的原因
最好的解决方案是正确定义输入结构,包括union部分。这样做(声明取自)
我试图改变这个,但它没有工作与x64再次(x86是罚款的变化)。谢谢。@Ben:你的尺码不对。大小随位的不同而变化,因此您无法指定它。是的,请删除LayoutKind.Explicit,size=28
和FieldOffset
属性。@David Heffernan如果删除这些属性,x86或x64都不起作用。我相信他们是需要的。我尝试将28->32和FieldOffset更改为8,只是想看看是否可以让x64正常工作,而不需要使用LayoutKind.Sequential。是默认的LayoutKind.Automatic吗?我不确定。不知何故,一些代码丢失了,因此相关行应该是[StructLayout(LayoutKind.Explicit,Size=28)]
当我开始这个项目时,我不得不使用SendInput是有原因的,但我不记得为什么了。然而,这是有效的!非常感谢你!
[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
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
[StructLayout(LayoutKind.Explicit)]
struct MouseKeybdHardwareInputUnion
{
[FieldOffset(0)]
public MOUSEINPUT mi;
[FieldOffset(0)]
public KEYBDINPUT ki;
[FieldOffset(0)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct INPUT
{
public uint type;
public MouseKeybdHardwareInputUnion mkhi;
}