4

我们有一个打印驱动程序,它在驱动程序的 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 挂钩或代码注入的技术,因为这些操作往往会被防病毒软件标记。

4

1 回答 1

4

我从引用的修补程序中假设您的目标是 Vista 之后的计算机。

GetPrintExecutionData功能看起来可以提供您想要的信息。它确实假设您在假脱机程序的上下文中运行,但从问题来看,这似乎不是问题。该函数返回一个PRINT_EXECUTION_DATA带有成员的结构

[...]clientAppPID [which] 标识 splwow64.exe 进程代表其加载打印机驱动程序的客户端应用程序。

KB2815716 中提到的问题可能仍然会影响这一点。我假设 KB 安装已经过验证,并且超时是默认值(2 分钟)或非零。KB 对于请求打印的进程是否必须终止,或者打印作业是否必须终止有点模棱两可。此外,如果终端服务以任何方式与打印有关,如 中KB2513330,那么您可能需要设置Sysprocs密钥。

于 2015-09-01T00:22:53.133 回答