我使用以下代码使用SendInput
传递特殊密钥。我面临一个奇怪的问题。如果用户发送 Alt / Ctrl / Shift 中的任何一个,则密钥保持按下,例如如果用户传递 Alt + F4 ,则代码正常运行并且操作成功完成,但 Alt 键仍然按下。操作完成后,我需要手动单击 Alt 键。请让我知道在代码本身处理相同的问题。以下是用于发送特殊密钥的代码。
namespace RemoteDesktopSendKeys
{
class Program
{
struct INPUT
{
public INPUTType type;
public INPUTUnion Event;
}
[StructLayout(LayoutKind.Explicit)]
struct INPUTUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public KEYEVENTF dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
enum INPUTType : uint
{
INPUT_KEYBOARD = 1
}
[Flags]
enum KEYEVENTF : uint
{
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
SCANCODE = 0x0008,
UNICODE = 0x0004
}
[DllImport("user32.dll", SetLastError = true)]
static extern UInt32 SendInput(int numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
[DllImport("user32.dll")]
public static extern IntPtr GetMessageExtraInfo();
[System.Runtime.InteropServices.DllImport("user32.dll")]
internal static extern uint MapVirtualKey(uint uCode, uint uMapType);
private const int KEYEVENTF_KEYUP1 = 0x0002;
[DllImport("user32.dll")]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int MapVirtualKey(int uCode, int uMapType);
static void Main(string[] args)
{
Thread.Sleep(3000);
int[] keyboardStrokes = { (int)Keys.LMenu,(int)Keys.F4 };
//int[] keyboardStrokes = { (int)Keys.ControlKey, (int)Keys.A };
SendSpecialKeys("test", keyboardStrokes);
//SendSpecialKeys("F5",keyboardStrokes);
}
private static void SendSpecialKeys(string text, int[] modifiers)
{
List<int> arrKeys = new List<int>();
Keys key;
if (modifiers != null && modifiers.Length > 0)
{
for (int i = 0; i < modifiers.Length; i++)
{
arrKeys.Add(modifiers[i]);
}
}
if (!string.IsNullOrEmpty(text))
{
if (Enum.TryParse(text, out key))
arrKeys.Add((int)key);
else
SendText(text);
}
System.Threading.Thread.Sleep(1000);
int[] arrKeyStrokes = arrKeys.ToArray();
INPUT[] inputs = new INPUT[arrKeyStrokes.Length + 1];
for (int i = 0; i < arrKeyStrokes.Length; i++)
{
uint skey = MapVirtualKey((uint)arrKeyStrokes[i], (uint)0x0);
inputs[i].type = INPUTType.INPUT_KEYBOARD;
inputs[i].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
inputs[i].Event.ki.wScan = (ushort)skey;
}
inputs[arrKeyStrokes.Length].type = INPUTType.INPUT_KEYBOARD;
inputs[arrKeyStrokes.Length].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
inputs[arrKeyStrokes.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
}
public static void SendText(string text)
{
List<INPUT> kbInput = new List<INPUT>();
foreach (char c in text)
{
// Send a key down followed by key up.
foreach (bool keyUp in new bool[] { false, true })
{
INPUT input = new INPUT
{
type = INPUTType.INPUT_KEYBOARD,
Event = new INPUTUnion
{
// This will contain keyboard event information
ki = new KEYBDINPUT
{
wVk = 0,
wScan = c,
dwFlags = KEYEVENTF.UNICODE | (keyUp ? KEYEVENTF.KEYUP : 0),
dwExtraInfo = GetMessageExtraInfo(),
}
}
};
kbInput.Add(input);
}
}
// Call SendInputWindows API to send input
SendInput((int)kbInput.Count, kbInput.ToArray(), Marshal.SizeOf(typeof(INPUT)));
}
}
}
答案 0 :(得分:0)
以下代码可用于释放特定密钥。下面是释放控制键的示例代码。
uint ctrlkey = MapVirtualKey((uint)Keys.ControlKey, (uint)0x0);
inputs[index].type = INPUTType.INPUT_KEYBOARD;
inputs[index].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
inputs[index].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
inputs[index].Event.ki.wScan = (ushort)ctrlkey;
需要通过正确传递索引来确保释放正确的密钥。