C# 键盘记录器如何显著提高PostMessage()的性能

C# 键盘记录器如何显著提高PostMessage()的性能,c#,.net,winforms,winapi,C#,.net,Winforms,Winapi,我想通过在干净的状态下运行系统上的“基准测试”,安装键盘记录程序并重复基准测试,看看是否能够检测到系统上是否存在键盘记录程序。其想法是,键盘记录器需要消耗资源才能正确运行,并应导致较低的基准分数 在代码中,我基本上编写了两个while循环,使用win32API调用SendMessage()和PostMessage()来模拟击键。它在给定的时间内执行循环,并记录发送的成功消息数 我希望键盘记录程序不会产生可测量的差异(毕竟,桌面上一直有很多“东西”在执行,我认为键盘记录程序可能不会使用太多…),或

我想通过在干净的状态下运行系统上的“基准测试”,安装键盘记录程序并重复基准测试,看看是否能够检测到系统上是否存在键盘记录程序。其想法是,键盘记录器需要消耗资源才能正确运行,并应导致较低的基准分数

在代码中,我基本上编写了两个while循环,使用win32API调用SendMessage()和PostMessage()来模拟击键。它在给定的时间内执行循环,并记录发送的成功消息数

我希望键盘记录程序不会产生可测量的差异(毕竟,桌面上一直有很多“东西”在执行,我认为键盘记录程序可能不会使用太多…),或者它会导致数字稍微降低

这就是我在“SendMessage()”调用中看到的情况

我不明白的是,我的基准测试显示对PostMessage()的调用数量急剧增加

在安装键盘记录器之前,平均执行多次,我每秒看到大约10k PostMessage()。在安装了键盘记录器之后,我现在看到每秒有近25k次对PostMessage()的调用

这对我来说毫无意义

如果我对PostMessage的理解是正确的,它会将一条windows消息添加到进程的消息队列中并继续执行(而SendMessage会等待进程处理消息后再返回)。我希望PostMessage的执行速度比SendMessage快,而且一旦消息队列满了,一些消息可能会丢失……但我有限的理解并不能帮助我理解键盘记录程序是如何通过如此大的幅度提高性能的

我觉得代码很简单。我可以确认它确实注册为击键(我将它们发送到记事本中),并且键盘记录器正在记录它们

有人能解释一下我错过了什么吗

键盘记录器如何提高性能

更新 我正在运行基准测试10次,并对结果取平均值。
暂停键盘记录器(使其仍然安装,但不记录)仍然会产生较高的结果。在卸载键盘记录器并重新启动我的机器后,平均每秒运行10次是9.9k;与我最初的结果非常一致


我必须重新启动计算机才能完成卸载。

没有太多限制PostMessage()调用的因素。在内部,它必须获取一个锁来访问线程的消息队列,以安全的方式追加消息。这里的异常情况是,如果没有记录器,这样做的速度非常慢,每秒10K的调用并不多。只要应用程序正在清空队列,Windows内部可能会有一个节流阀在短时间内阻止呼叫。不知道这是不是真的

这在很大程度上取决于键盘记录器使用的钩子,有不止一个候选钩子。但是没有钩子来检测消息是否被添加到队列中,只有当从队列中检索到消息并将其发送到窗口时。如WH_GETMESSAGE、WH_CALLWNDPROC或WH_CALLWNDPROCRET。因此,接下来的情况是,记录器会使清空队列的速度变慢

这为您看到的情况提供了一个解释,如果您调用PostMessage()而不进行节流,则会使消息队列溢出。默认情况下,它只能包含10000条消息。如果你溢出它,你将得到一个快速的回报,你将衡量一个更高的利率


所以我猜您忘了查看PostMessage()的返回值。当无法添加消息时,返回FALSE。

最好调用有趣的问题。暂停/卸载键盘记录器后,性能是否再次下降?这将确保性能差异实际上是由键盘记录器引起的,而不是在重新执行基准测试时进行的其他优化(例如Windows或.NET运行时负责的优化)@erikkallen-谢谢-我会查看SendInput,看看这是否有助于澄清问题。您还可以检查GetLastError是否返回了某些内容,因此您的代码没有完全按照路径运行。我们需要您的代码源和键盘记录程序的源来理解和解释发生了什么。