17

我有一个在库中使用键盘挂钩程序的应用程序。一条消息的钩子中的 wParam 是 255,我们认为它是“(保留 / OEMClear)”。我想弄清楚这条消息的来源,因为它会导致我的应用程序在库中崩溃,并且鉴于它不应该发生,最好识别它。该消息仅在我们拥有的一台 PC 上重复出现 - 其他计算机根本看不到该消息。

那么,有没有办法追踪发送到窗口的消息的来源,或者系统上的所有消息?

4

4 回答 4

7

没有内置方法可以找出谁发送了窗口消息,甚至 win32k 也没有跟踪这一点;您也许可以使用内核调试器和条件断点找到它。

但是,我认为您并不真的需要这些信息。您需要使您的应用程序正确处理发送给它的任何消息。

于 2009-05-26T15:54:29.767 回答
1

(我最初建议使用 Spy++ 或 winspector,但它们不会与消息的发送挂钩。这甚至没有意义!窗口接收消息但他们不发送消息,线程会这样做。我会离开我的关于使用调试器的建议。)

有时调试会有所帮助。尝试下载 Windows PDB文件并设置一个断点,该断点仅在出现这些消息之一时才命中。在这一点上查看调用堆栈通常可以对事情发生的原因有所了解。发布的消息和从其他进程发送的消息将挫败这种方法。

于 2009-05-26T15:24:43.413 回答
1

我想出了一种技术,用于确定谁在一次性调试/故障排除会话期间跨线程/进程发送 win32 窗口消息。它需要做出几个假设,所以它不是 100% 可靠的,但到目前为止我还没有发现它不起作用的情况。

基本思想是利用这样一个事实,即当消息到达时,接收窗口线程通常被阻塞在其消息循环中等待GetMessage()(特别是, )。当消息被传递时,发送线程准备接收线程,将其拉出等待状态。

事实证明,Windows 提供了使用Windows 事件跟踪来精确跟踪哪些线程正在准备哪些其他线程的方法。使用这个特性,通常可以确定哪个线程发送了消息——它是准备接收线程的线程。甚至可以看到发送线程在发送消息时的调用堆栈是什么,甚至可以看到堆栈的内核端 ( win32k) 部分!

基本程序是这样的:

  1. 使用Windows 性能记录器启动跟踪。确保包含“CPU 使用率”配置文件。
  2. 触发发送您感兴趣的消息。
  3. 停止追踪。
  4. 在Windows 性能分析器中打开跟踪。
  5. 在“CPU Usage (Precise)”图表中,“Stacks”图表预设,放大收到消息的时间。
    • 一种方法是定位接收线程并确定它何时醒来。
    • 如果关联很困难,则可能值得使用TraceLogging来检测接收线程以生成清晰的参考时间点。
  6. 您应该能够找到接收线程准备就绪的上下文切换事件GetMessage
  7. “Reading Process”、“Reading Thread Id”和“Reading Thread Stack”列将显示准备好的线程的详细信息,该线程很可能是消息的发送者。

例如,在下面的屏幕截图中,TID 7640 接收到来自 WindowsTerminal.exe、TID 1104的外壳挂钩消息:

WPA 截图

于 2022-02-05T11:28:30.500 回答
-3

我不确定这是否符合您的要求,但请查看 sysinternals 的 Process Monitor。

http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx

它显示了进程发生的所有事情,所以我假设它也捕获消息。该网站在撰写本文时已关闭,因此我无法检查。

于 2009-05-26T14:59:08.457 回答