我正在运行一个c#应用程序,该应用程序利用windows中的sendinputs方法来模拟击键。当我远程登录到实例时,它工作正常,但是一旦我注销它就抛出异常。任何人都可以提出任何关于为什么会发生这种情况的想法,以及如何避免它?
UPDATE :: 这里有一些可以重现问题的示例代码。
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ConsoleApplication6
{
class Program
{
class SendKey
{
[StructLayout(LayoutKind.Sequential)]
private struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public int dwExtraInfo;
};
[StructLayout(LayoutKind.Sequential)]
private struct KEYBDINPUT
{
public short wVk;
public short wScan;
public int dwFlags;
public int time;
public int dwExtraInfo;
};
[StructLayout(LayoutKind.Sequential)]
private struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
};
[StructLayout(LayoutKind.Explicit)]
private struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(4)]
public MOUSEINPUT no;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
};
[DllImport("user32.dll")]
private extern static void SendInput(int nInputs, ref INPUT pInputs, int cbsize);
[DllImport("user32.dll", EntryPoint = "MapVirtualKeyA")]
private extern static int MapVirtualKey(int wCode, int wMapType);
private const int INPUT_KEYBOARD = 1;
private const int KEYEVENTF_KEYDOWN = 0x0;
private const int KEYEVENTF_KEYUP = 0x2;
private const int KEYEVENTF_EXTENDEDKEY = 0x1;
private void Send(Keys key, bool isEXTEND)
{
INPUT inp = new INPUT();
inp.type = INPUT_KEYBOARD;
inp.ki.wVk = (short)key;
inp.ki.wScan = (short)MapVirtualKey(inp.ki.wVk, 0);
inp.ki.dwFlags = ((isEXTEND) ? (KEYEVENTF_EXTENDEDKEY) : 0x0) | KEYEVENTF_KEYDOWN;
inp.ki.time = 0;
inp.ki.dwExtraInfo = 0;
SendInput(1, ref inp, Marshal.SizeOf(inp));
System.Threading.Thread.Sleep(100);
inp.ki.dwFlags = ((isEXTEND) ? (KEYEVENTF_EXTENDEDKEY) : 0x0) | KEYEVENTF_KEYUP;
SendInput(1, ref inp, Marshal.SizeOf(inp));
}
static void Main()
{
while(true)
{
System.Threading.Thread.Sleep(2000);
SendKey s = new SendKey();
s.Send(Keys.Z, false);
s.Send(Keys.Left, true);
}
}
}
}
}
如果你构建这个并且只是在一个免费的Windows服务器ec2实例上运行它,并且记事本处于焦点,那么当你远程访问实例时它将连续打印zzzzzz,但是,只要你远离实例,它就会停止打印,直到您重新登录。