C# SendInput() 在控制台应用程序中总是 returns 0
C# SendInput() always returns 0 in Console Application
我开发了一个简单的控制台应用程序来使用 xinput 轮询 Xbox 控制器。我想使用从其中一根拇指杆获得的值来移动鼠标。我能够从拇指杆获取 x 和 y 值,但是当我将这些值用于 SendInput()(使用 User32.dll)时,鼠标不会移动并且 return 值为 0。
根据Microsoft、"If the function returns zero, the input was already blocked by another thread."
如何找到阻塞它的其他线程?它只是一个简单的控制台应用程序 (exe),由 Visual Studio 启动,将 x 和 y 值打印到屏幕并尝试移动鼠标。
long x = controller.x; // values from the controller
long y = controller.y; // these are checked and do contain numbers
INPUT mouseMoveInput = new INPUT();
mouseMoveInput.type = 0; // mouse
mouseMoveInput.mi.dx = x;
mouseMoveInput.mi.dy = y;
mouseMoveInput.mi.mouseData = 0;
mouseMoveInput.mi.dwFlags = MOUSEEVENTF_MOVE;
var result = SendInput(1, ref mouseMoveInput, Marshal.SizeOf(new INPUT());
// result always returns 0
我错过了什么吗?这应该有效吗?
声明如下:
[StructLayout(LayoutKind.Explicit)]
public struct MOUSEINPUT
{
[FieldOffset(0)]
public long X;
[FieldOffset(8)]
public long Y;
[FieldOffset(16)]
public uint MouseData;
[FieldOffset(20)]
public uint Flags;
[FieldOffset(24)]
public uint Time;
[FieldOffset(28)]
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBOARDINPUT
{
public ushort Vk;
public ushort Scan;
public uint Flags;
public uint Time;
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
public uint Msg;
public ushort ParamL;
public ushort ParamH;
}
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBOARDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
更新:使用 mouse-event
确实有效,但此功能已弃用。既然能用了,用起来有问题吗?
结构大小有些奇怪:
标签输入的大小:40
mouseMoveInput 的大小:40
MOUSEINPUT 的大小:32
uint 的大小:4
但是如果 tagINPUT
由 MOUSEINPUT
和 uint
组成,那么它的大小不应该是 36 吗?
SendInput
的第二个参数应该是指向数组的指针,而不是 ref 参数,尤其不是直接指向结构的 ref。
我也会只对实际需要它的结构使用显式布局,让其余部分按顺序排列。更简单。
这段代码对我有用:
const int INPUT_MOUSE = 0;
const int MOUSEEVENTF_MOVE = 0x0001;
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray)] INPUT[] inputs, int sizeOfInputStructure);
void Main()
{
INPUT mouseMoveInput = new INPUT();
mouseMoveInput.type = INPUT_MOUSE;
mouseMoveInput.mi.dx = 10;
mouseMoveInput.mi.dy = 10;
mouseMoveInput.mi.mouseData = 0;
mouseMoveInput.mi.dwFlags = MOUSEEVENTF_MOVE;
var result = SendInput(1, new INPUT[] { mouseMoveInput}, Marshal.SizeOf(mouseMoveInput));
if(result == 0) {
throw new Win32Exception();
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct HARDWAREINPUT
{
public uint Msg;
public ushort ParamL;
public ushort ParamH;
}
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
我开发了一个简单的控制台应用程序来使用 xinput 轮询 Xbox 控制器。我想使用从其中一根拇指杆获得的值来移动鼠标。我能够从拇指杆获取 x 和 y 值,但是当我将这些值用于 SendInput()(使用 User32.dll)时,鼠标不会移动并且 return 值为 0。
根据Microsoft、"If the function returns zero, the input was already blocked by another thread."
如何找到阻塞它的其他线程?它只是一个简单的控制台应用程序 (exe),由 Visual Studio 启动,将 x 和 y 值打印到屏幕并尝试移动鼠标。
long x = controller.x; // values from the controller
long y = controller.y; // these are checked and do contain numbers
INPUT mouseMoveInput = new INPUT();
mouseMoveInput.type = 0; // mouse
mouseMoveInput.mi.dx = x;
mouseMoveInput.mi.dy = y;
mouseMoveInput.mi.mouseData = 0;
mouseMoveInput.mi.dwFlags = MOUSEEVENTF_MOVE;
var result = SendInput(1, ref mouseMoveInput, Marshal.SizeOf(new INPUT());
// result always returns 0
我错过了什么吗?这应该有效吗?
声明如下:
[StructLayout(LayoutKind.Explicit)]
public struct MOUSEINPUT
{
[FieldOffset(0)]
public long X;
[FieldOffset(8)]
public long Y;
[FieldOffset(16)]
public uint MouseData;
[FieldOffset(20)]
public uint Flags;
[FieldOffset(24)]
public uint Time;
[FieldOffset(28)]
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct KEYBOARDINPUT
{
public ushort Vk;
public ushort Scan;
public uint Flags;
public uint Time;
public IntPtr ExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HARDWAREINPUT
{
public uint Msg;
public ushort ParamL;
public ushort ParamH;
}
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBOARDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
更新:使用 mouse-event
确实有效,但此功能已弃用。既然能用了,用起来有问题吗?
结构大小有些奇怪:
标签输入的大小:40
mouseMoveInput 的大小:40
MOUSEINPUT 的大小:32
uint 的大小:4
但是如果 tagINPUT
由 MOUSEINPUT
和 uint
组成,那么它的大小不应该是 36 吗?
SendInput
的第二个参数应该是指向数组的指针,而不是 ref 参数,尤其不是直接指向结构的 ref。
我也会只对实际需要它的结构使用显式布局,让其余部分按顺序排列。更简单。
这段代码对我有用:
const int INPUT_MOUSE = 0;
const int MOUSEEVENTF_MOVE = 0x0001;
[DllImport("user32.dll", SetLastError = true)]
private static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray)] INPUT[] inputs, int sizeOfInputStructure);
void Main()
{
INPUT mouseMoveInput = new INPUT();
mouseMoveInput.type = INPUT_MOUSE;
mouseMoveInput.mi.dx = 10;
mouseMoveInput.mi.dy = 10;
mouseMoveInput.mi.mouseData = 0;
mouseMoveInput.mi.dwFlags = MOUSEEVENTF_MOVE;
var result = SendInput(1, new INPUT[] { mouseMoveInput}, Marshal.SizeOf(mouseMoveInput));
if(result == 0) {
throw new Win32Exception();
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct HARDWAREINPUT
{
public uint Msg;
public ushort ParamL;
public ushort ParamH;
}
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}