如何使用C#按键并释放?

如何使用C#按键并释放?,c#,keyboard,C#,Keyboard,我正在编写一个C#程序,它从外部设备捕获信号,并将击键发送到另一个应用程序。我使用SendKeys,它工作正常 SendKeys通过按住并立即释放键来“按下”键。我想让它按一下键,然后随意释放 我的问题是:“有没有一种方法可以向钥匙发送“推”信号,然后在一定时间后发送“释放”信号?” 我不确定SendKeys是否能够做到这一点。有什么线索吗?我认为不可能直接从.NET获得 您可以尝试使用keybd_事件本机调用,方法是p/调用函数,如下所述: keybd_事件的MSDN如下所示: 希望有帮助 您

我正在编写一个C#程序,它从外部设备捕获信号,并将击键发送到另一个应用程序。我使用SendKeys,它工作正常

SendKeys通过按住并立即释放键来“按下”键。我想让它按一下键,然后随意释放

我的问题是:“有没有一种方法可以向钥匙发送“推”信号,然后在一定时间后发送“释放”信号?”


我不确定SendKeys是否能够做到这一点。有什么线索吗?

我认为不可能直接从.NET获得 您可以尝试使用keybd_事件本机调用,方法是p/调用函数,如下所述:

keybd_事件的MSDN如下所示:


希望有帮助

您可以使用SendInput或keyb_事件,两者都是本机API函数。SendInput与keybd_事件相比有一些优势,但SendInput仅从XP开始提供

这里是msdn链接


希望这有帮助

我曾经想在powerpoint上做同样的事情,隐藏光标,然后停止幻灯片放映。但这很难,也很棘手,因为powerpoint中出现了许多顶级窗口,而且很难确定哪部分仿真失败了。在使用Spy++查看消息队列之后,我注意到accelerator命令是在按键之后发送的,因此,我模拟了accelerator命令,它的工作原理与charm类似。因此,您可能希望研究类似的替代方案。

接受的答案使用了
keybd\u事件,这是不推荐的。官方API现已发布。还有一个很好的包装

然而,上述任何一项都不能完全满足“持有钥匙”的情况。这是因为,按住一个键将生成多条
WM_KEYDOWN
消息,然后在释放时生成一条
WM_keydup
消息(您可以使用Spy++进行检查)

WM_KEYDOWN
消息的频率取决于硬件、BIOS设置和两个Windows设置:和。后者可从Windows窗体(,)访问

使用前面提到的输入模拟器库,我实现了一个模拟实际行为的键保持方法。它是
await/async
ready,支持取消

static Task SimulateKeyHold(VirtualKeyCode key, int holdDurationMs, 
                            int repeatDelayMs, int repeatRateMs, CancellationToken token)
{
    var tcs = new TaskCompletionSource<object>();
    var ctr = new CancellationTokenRegistration();
    var startCount = Environment.TickCount;
    Timer timer = null;
    timer = new Timer(s =>         
    {
        lock (timer)
        {
            if (Environment.TickCount - startCount <= holdDurationMs)
                InputSimulator.SimulateKeyDown(key);
            else if (startCount != -1)
            { 
                startCount = -1; 
                timer.Dispose();
                ctr.Dispose();                    
                InputSimulator.SimulateKeyUp(key);
                tcs.TrySetResult(null);
            }
        }
    });
    timer.Change(repeatDelayMs, repeatRateMs);

    if (token.CanBeCanceled)
        ctr = token.Register(() =>
                       {
                           timer.Dispose();
                           tcs.TrySetCanceled();
                       });
    return tcs.Task;
}
static Task SimulateKeyHold(VirtualKeyCode键,int-holdDurationMs,
int repeatDelayMs、int repeatRateMs、CancellationToken令牌)
{
var tcs=new TaskCompletionSource();
var ctr=新的CancellationTokenRegistration();
var startCount=Environment.TickCount;
计时器=空;
定时器=新定时器(s=>
{
锁(定时器)
{
if(Environment.TickCount-startCount
{
timer.Dispose();
tcs.trysetconceled();
});
返回tcs.Task;
}

非常感谢您的宝贵意见。