我想做一个c#应用程序,这将控制一个游戏。我想做的是,例如:按住A键150毫秒,按住左箭头500毫秒,等等。我搜索了很多,我发现了以下代码。我的程序首先以游戏为目标,然后再拿着按键。
I'm holding the keys this way:
Keyboard.HoldKey(Keys.Left);
Thread.sleep(500);
Keyboard.ReleaseKey(Keys.Left);
下面是Keyboard类:
public class Keyboard
{
public Keyboard()
{
}
[StructLayout(LayoutKind.Explicit, Size = 28)]
public struct Input
{
[FieldOffset(0)]
public uint type;
[FieldOffset(4)]
public KeyboardInput ki;
}
public struct KeyboardInput
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public long time;
public uint dwExtraInfo;
}
const int KEYEVENTF_KEYUP = 0x0002;
const int INPUT_KEYBOARD = 1;
[DllImport("user32.dll")]
public static extern int SendInput(uint cInputs, ref Input inputs, int cbSize);
[DllImport("user32.dll")]
static extern short GetKeyState(int nVirtKey);
[DllImport("user32.dll")]
static extern ushort MapVirtualKey(int wCode, int wMapType);
public static bool IsKeyDown(Keys key)
{
return (GetKeyState((int)key) & -128) == -128;
}
public static void HoldKey(Keys vk)
{
ushort nScan = MapVirtualKey((ushort)vk, 0);
Input input = new Input();
input.type = INPUT_KEYBOARD;
input.ki.wVk = (ushort)vk;
input.ki.wScan = nScan;
input.ki.dwFlags = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
SendInput(1, ref input, Marshal.SizeOf(input)).ToString();
}
public static void ReleaseKey(Keys vk)
{
ushort nScan = MapVirtualKey((ushort)vk, 0);
Input input = new Input();
input.type = INPUT_KEYBOARD;
input.ki.wVk = (ushort)vk;
input.ki.wScan = nScan;
input.ki.dwFlags = KEYEVENTF_KEYUP;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
SendInput(1, ref input, Marshal.SizeOf(input));
}
public static void PressKey(Keys vk)
{
HoldKey(vk);
ReleaseKey(vk);
}
}
和它的工作在记事本/浏览器等,但它不工作在任何游戏,无论是全屏或窗口模式。你能帮我弄清楚如何在全屏应用程序/游戏中按住键吗?谢谢!
"按住A键150ms,按住左箭头500ms"
查看是否成功:
Keyboard.HoldKey((byte)Keys.A, 150);
Keyboard.HoldKey((byte)Keys.Left, 500);
使用:public class Keyboard
{
[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
const int KEY_DOWN_EVENT = 0x0001; //Key down flag
const int KEY_UP_EVENT = 0x0002; //Key up flag
public static void HoldKey(byte key, int duration)
{
int totalDuration = 0;
while (totalDuration < duration)
{
keybd_event(key, 0, KEY_DOWN_EVENT, 0);
keybd_event(key, 0, KEY_UP_EVENT, 0);
System.Threading.Thread.Sleep(PauseBetweenStrokes);
totalDuration += PauseBetweenStrokes;
}
}
}
你可以让它工作,这是很好的按住键:
public class Keyboard
{
const int PauseBetweenStrokes = 50;
[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
const int KEY_DOWN_EVENT = 0x0001; //Key down flag
const int KEY_UP_EVENT = 0x0002; //Key up flag
public static void HoldKey(byte key, int duration)
{
keybd_event(key, 0, KEY_DOWN_EVENT, 0);
System.Threading.Thread.Sleep(duration);
keybd_event(key, 0, KEY_UP_EVENT, 0);
}
}
我使用了Windown API和SendInput方法。
如果将Keyboard类定义为:
public static class Keyboard
{
[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
public static void Delay(int delay)
{
System.Threading.Thread.Sleep(delay);
}
public static void KeyDown(KEYCODE keycode)
{
keybd_event((byte)keycode, 0x0, 0, 0);// presses
}
public static void KeyPress(KEYCODE keycode, int delay = 0)
{
keybd_event((byte)keycode, 0x0, 0, 0);// presses
System.Threading.Thread.Sleep(delay);
keybd_event((byte)keycode, 0x0, 2, 0); //releases
}
public static void KeyUp(KEYCODE keycode)
{
keybd_event((byte)keycode, 0, 2, 0); //release
}
public static void Type(string message)
{
System.Windows.Forms.SendKeys.SendWait(message);
}
}
键码为
public enum KEYCODE {
VK_A = 0x41, VK_B = 0x42, VK_C = 0x43, VK_D = 0x44, VK_E = 0x45, VK_F = 0x46, VK_G = 0x47,
VK_H = 0x48, VK_I = 0x49, VK_J = 0x4A, VK_K = 0x4B, VK_L = 0x4C, VK_M = 0x4D, VK_N = 0x4E, VK_O = 0x4F,
VK_P = 0x50, VK_Q = 0x51, VK_R = 0x52, VK_S = 0x53, VK_T = 0x54, VK_U = 0x55, VK_V = 0x56, VK_W = 0x57,
VK_X = 0x58, VK_Y = 0x59, VK_Z = 0x5A, VK_LSHIFT = 0xA0, VK_RSHIFT = 0xA1, VK_LCONTROL = 0xA2, VK_RCONTROL = 0xA3
}
可以执行如下命令:
Keyboard.KeyDown(KEYCODE.VK_LSHIFT);
Keyboard.KeyPress(KEYCODE.VK_V);
Keyboard.KeyUp(KEYCODE.VK_LSHIFT);
Keyboard.KeyPress(KEYCODE.VK_I);
Keyboard.KeyPress(KEYCODE.VK_N);
Keyboard.KeyPress(KEYCODE.VK_O);
Keyboard.KeyPress(KEYCODE.VK_D);
并且由于按下了shift键,它将打印Vinod
,使V
大写。但是如果你想发送多个按键,比如输入文本,你可以使用Keyboard.Type()
来代替,比如
Keyboard.Type("+vino+d");
,它将打印VinoD
,使V
和D
大写,更多帮助请参阅这里的文档
我甚至写了一个叫做Robot.cs的东西,它有键盘,鼠标和;过程自动化。