我正在编写一些开源软件来捕获和处理原始鼠标和键盘事件。捕获事件时,我会与win32窗口进行通信,以确切地询问如何处理事件(即传递或使用它)。它实际上与HIDMacros非常相似。
最终决定是否使用事件的部分实际上是在我无法控制的内存空间中运行(即Windows本身正在运行的内容)。遗憾的是,这意味着我几乎没有能力调试该部分代码。幸运的是,这是非常简单的代码,我还没有调试它。
另一方面,我有一个在自己的线程中运行的Win32事件循环,并处理上述代码段发送的请求。因此,上面的部分向该窗口发送一条消息,它决定要做什么,并返回一个答案。很简单。
问题是这个。当我附加调试器时,只停止win32窗口事件循环。其他代码保持正常运行,因为它不在我的实际内存或进程中。当用户做了类似的事情,哦,按F10(进入下一行),我注册的键盘钩子将(1)抓住击键,(2)调用我的win32窗口进行操作回答。不幸的是,调试器冻结了窗口。最终结果是:我按下F10,视觉工作室从未接受我的击键。 Visual Studio本身停止响应所有输入,它冻结,我必须杀死VS本身。
现在我已经设法通过使用超时来解决SOMEWHAT问题,但它真的很烦人(即非常明显)并且根本不理想。我想知道的是,是否有一种以编程方式从调试器中排除特定线程?有没有办法要求VS调试器不要停止执行特定线程?除此之外,有没有办法让调试器本身在暂停正常执行之前执行某个操作,并在恢复正常执行后再次执行?
此库将用于其他项目。我真的很喜欢它,如果人们在调试JUST时突然失去了使用键盘的能力,因为他们决定链接到我的库。 :)感谢任何帮助。谢谢。
答案 0 :(得分:1)
Hmya,你正在使用全局钩子,非常具有破坏性。你无法用调试器做什么,它是注入到Visual Studio中的DLL的副本,它使SendMessageTimeout()调用挂起。 IsDebuggerPresent()不会有用。
一种可能的解决方法是检查DLL注入的进程。在你得到的第一个回调中使用GetModuleFileHandle,传递NULL。如果你看到devenv.exe,那么永远绕过一切。请注意,这是本地状态,不是共享状态。
另一种方法是在第一次超时时切换模式。当发生这种情况时,绕过SendMessage调用一段时间(比如5分钟),以便这些超时不再那么明显。
答案 1 :(得分:0)
你并没有确切地说你对超时做了什么,而你并没有确切地说你的过滤器进程正在做什么,但我会使用SendMessageTimeout而不是普通的SendMessage,并且具有相当低的超时值,然后如果SendMessageTimeout超时,则继续挂钩。
答案 2 :(得分:0)
VS使用的调试器api(实际上每隔一个调试器)将始终冻结整个过程。