C# 模拟键盘输入以进行处理时出现问题
我试图用c#模拟某个进程的键盘输入。 输入字符和数字很好,但当我尝试模拟一个“特殊字符”(回车、制表符等)按键时,什么也没发生 让我印象深刻的是,模拟这些特殊角色在其他进程(如Skype)上效果很好 你知道是什么导致了这种奇怪的互动吗?我也愿意尝试其他语言的东西,因为我在我的项目中还没有走那么远C# 模拟键盘输入以进行处理时出现问题,c#,process,keyboard,postmessage,simulate,C#,Process,Keyboard,Postmessage,Simulate,我试图用c#模拟某个进程的键盘输入。 输入字符和数字很好,但当我尝试模拟一个“特殊字符”(回车、制表符等)按键时,什么也没发生 让我印象深刻的是,模拟这些特殊角色在其他进程(如Skype)上效果很好 你知道是什么导致了这种奇怪的互动吗?我也愿意尝试其他语言的东西,因为我在我的项目中还没有走那么远 我试过使用and,它们都有相同的结果,输入字符有效,但没有特殊的键。我设法解决了这个问题。我将发布我的解决方案,以防有人偶然发现这篇文章与我遇到的问题相同 解决办法其实相当简单。如果您不发送虚拟键代码而
我试过使用and,它们都有相同的结果,输入字符有效,但没有特殊的键。我设法解决了这个问题。我将发布我的解决方案,以防有人偶然发现这篇文章与我遇到的问题相同 解决办法其实相当简单。如果您不发送虚拟键代码而发送键盘扫描代码,则一切正常。 这里有一个简单的例子
using System.Runtime.InteropServices;
...
public static void PressEnter()
{
INPUT input = new INPUT();
input.type = (int)InputType.INPUT_KEYBOARD;
input.ki.wScan = 0x1C;
input.ki.dwFlags = (int)KEYEVENTF.SCANCODE;
input.ki.dwExtraInfo = GetMessageExtraInfo();
var arrayToSend = new INPUT[] { input };
SendInput(1, arrayToSend, Marshal.SizeOf(input)); //Send KeyDown
arrayToSend[0].ki.dwFlags = (int)KEYEVENTF.SCANCODE | (int)KEYEVENTF.KEYUP;
SendInput(1, arrayToSend, Marshal.SizeOf(input)); //Send KeyUp
}
其他必要信息:
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(4)]
public HARDWAREINPUT hi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(0)]
public int type;
}
[StructLayout(LayoutKind.Sequential)]
public struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[Flags]
public enum InputType
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 2
}
[Flags]
public enum KEYEVENTF
{
KEYDOWN = 0,
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
UNICODE = 0x0004,
SCANCODE = 0x0008,
}
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetMessageExtraInfo();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
我设法解决了它。我将发布我的解决方案,以防有人偶然发现这篇文章与我遇到的问题相同 解决办法其实相当简单。如果您不发送虚拟键代码而发送键盘扫描代码,则一切正常。 这里有一个简单的例子
using System.Runtime.InteropServices;
...
public static void PressEnter()
{
INPUT input = new INPUT();
input.type = (int)InputType.INPUT_KEYBOARD;
input.ki.wScan = 0x1C;
input.ki.dwFlags = (int)KEYEVENTF.SCANCODE;
input.ki.dwExtraInfo = GetMessageExtraInfo();
var arrayToSend = new INPUT[] { input };
SendInput(1, arrayToSend, Marshal.SizeOf(input)); //Send KeyDown
arrayToSend[0].ki.dwFlags = (int)KEYEVENTF.SCANCODE | (int)KEYEVENTF.KEYUP;
SendInput(1, arrayToSend, Marshal.SizeOf(input)); //Send KeyUp
}
其他必要信息:
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(4)]
public HARDWAREINPUT hi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(0)]
public int type;
}
[StructLayout(LayoutKind.Sequential)]
public struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[Flags]
public enum InputType
{
INPUT_MOUSE = 0,
INPUT_KEYBOARD = 1,
INPUT_HARDWARE = 2
}
[Flags]
public enum KEYEVENTF
{
KEYDOWN = 0,
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
UNICODE = 0x0004,
SCANCODE = 0x0008,
}
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetMessageExtraInfo();
[DllImport("user32.dll", SetLastError = true)]
public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);