问题
I am using the below code to pass special keys using SendInput
. I am facing one strange issue. If user sends any of Alt/Ctrl/Shift, the key remains pressed e.g. if user passes Alt + F4, the code runs properly and action is completed successfully but Alt key remains pressed. I need to manually click Alt key after the operation is completed. Please let me know to handle the same in the code itself. Below is the code used to send special keys.
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)));
}
}
}
回答1:
The following code can be used to release particular key. Below is the sample code to release control key.
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;
Need to make sure that proper key is released by passing index properly.
来源:https://stackoverflow.com/questions/27278399/c-sharp-sendinput-alt-ctrl-shift-keys-not-getting-released