我们有一个打印驱动程序,它在驱动程序的 UI 模块中捕获打印 exe 的名称。它通过使用GetModuleFileName
函数来做到这一点。这在 64 位机器上打印 32 位之前效果很好。在这种情况下,Windows 调用 splwow64.exe 代表 32 位应用程序进行打印,因此GetModuleFileName
返回“splwow64.exe”作为打印应用程序,而不是实际执行打印的应用程序。
我们试图通过使用 Toolhelp32 API 捕获 splwow64.exe 的父进程来解决此问题,但这并不可靠,因为一旦第一个应用程序完成打印以服务其他应用程序,splwow64 就会保持加载状态。这意味着父进程可能是也可能不是实际打印的进程。到目前为止,我们一直找不到任何文件或命名管道或其他连接 splwow64 和打印应用程序的 IPC 对象。
Microsoft 发布了一个热修复程序 (KB2815716),它会导致 splwow64 在用户指定的超时期限后终止,但这并不能解决问题,因为只要调用它的第一个打印应用程序保持加载状态,splwow64.exe 就会无限期地保留在内存中。它完全忽略了热修复提供的超时。(我认为这是一个 Windows 错误。)
我的问题是这样的:
当它恰好是 32 位并且正在使用 splwow64.exe 时,我们需要一种可靠地确定正在打印的应用程序的方法。
该解决方案可以驻留在打印驱动程序或用户模式应用程序中——两者都可以。我们强烈不希望使用涉及 API 挂钩或代码注入的技术,因为这些操作往往会被防病毒软件标记。