我们有一个打印驱动程序,可以在驱动程序的UI模块中捕获打印exe的名称。它通过使用GetModuleFileName
函数来完成此操作。这在64位计算机上进行32位打印之前效果很好。在这种情况下,Windows调用splwow64.exe代表32位应用程序进行打印,因此GetModuleFileName
返回“splwow64.exe”作为打印应用程序,而不是实际执行打印的应用程序。
我们尝试通过使用Toolhelp32 API捕获splwow64.exe的父进程来解决这个问题,但这不可靠,因为一旦第一个应用程序完成打印以便为其他应用程序提供服务,splwow64仍然会加载。这意味着父进程可能是也可能不是实际打印的进程。到目前为止,我们无法找到连接splwow64和打印应用程序的任何文件或命名管道或其他IPC对象。
Microsoft发布了一个热修复程序(KB2815716),导致splwow64在用户指定的超时期限后终止,但这并不能解决问题,因为只要第一个调用它的打印应用程序,splwow64.exe就会无限期地保留在内存中仍然装满。它完全忽略了Hot Fix提供的超时。 (我认为这是一个Windows错误。)
我的问题是:
我们需要一种方法,可以确定哪个应用程序正在打印时,它正好是32位并且正在使用splwow64.exe。
解决方案可以驻留在打印驱动程序或用户模式应用程序中 - 两者都可以。我们强烈建议不要使用涉及API挂钩或代码注入的技术,因为这些操作往往会被反病毒软件标记。
答案 0 :(得分:3)
我从引用的修补程序中假设您在Vista之后定位了计算机。
GetPrintExecutionData
函数可以提供您想要的信息。它确实假设您在假脱机程序的上下文中运行,但从问题来看,这似乎不是问题。该函数返回带有成员
PRINT_EXECUTION_DATA
结构
[...] clientAppPID []代表splwow64.exe进程加载打印机驱动程序的客户端应用程序。
KB2815716中引用的问题可能仍会影响此问题。我假设KB安装已经过验证,超时是默认值(2分钟)或非零值。对于它是否是必须终止的请求打印的过程,或者它是否是必须终止的打印作业,KB有点模棱两可。此外,如果打印涉及终端服务(如KB2513330
中所述),则可能需要设置Sysprocs
密钥。