Windows服务打印PDF报Process has exited错误如何解决?
问题原因与解决方案
你遇到的Process has exited, so the requested information is not available报错,核心是你调用WaitForInputIdle()、CloseMainWindow()等进程操作方法时,你启动的PDF阅读器进程已经提前退出,无法读取进程状态信息。
根因分析
- Windows服务默认运行在非交互式的会话0中,无桌面交互权限,依赖UI环境的PDF阅读器根本无法正常启动,往往触发启动逻辑后直接闪退,导致后续进程操作调用时进程已经不存在。
- 你当前的进程启动逻辑直接将PDF文件设为
FileName,依赖Shell执行print动词,无法控制阅读器进程的生命周期:部分PDF阅读器是单实例运行,新的打印请求会复用已有进程,你启动的临时进程执行完指令后会直接退出,也会触发该异常。 - 打印逻辑没有做进程存活状态判断,直接调用仅在进程运行时生效的
WaitForInputIdle()、CloseMainWindow()方法,进程退出后调用就会抛出对应异常。
修复方案
1. 调整服务运行配置
打开Windows服务管理器,找到你部署的服务,右键进入「属性」-「登录」页:
- 勾选「允许服务与桌面交互」
- 配置服务运行账户为本地已安装PDF阅读器、有对应目录读写权限的管理员账户,不要使用默认的Local System账户
2. 优化进程启动逻辑
不要依赖Shell调用PDF文件的print动词,显式指定PDF阅读器的可执行文件路径,传入打印参数,可控性更强。以Adobe Acrobat Reader为例:
// 替换为你本地的阅读器实际安装路径 string readerPath = @"C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"; process.StartInfo.FileName = readerPath; // /t参数代表打印,后面依次跟PDF路径、打印机名(省略则用默认打印机) process.StartInfo.Arguments = $"/t \"{fi.FullName}\""; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true;
3. 优化进程等待逻辑
调用进程操作前先判断进程存活状态,避免调用已退出进程的方法:
process.Start(); // 最多等待3秒判断进程是否成功进入空闲状态 if (process.WaitForInputIdle(3000)) { // 最多等待15秒让打印完成,超时直接终止进程 if (!process.WaitForExit(15000)) { process.Kill(); } } else { // 进程已提前退出,若还未退出则强制终止 if (!process.HasExited) { process.Kill(); } }
4. 冗余逻辑优化
你当前的MoveFile方法不需要遍历源目录所有文件,直接操作传入的目标文件即可,可简化为:
public static void MoveFile(string filePath) { string targetPath = @"C:\fold1"; if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); } if (File.Exists(filePath)) { string destPath = Path.Combine(targetPath, Path.GetFileName(filePath)); File.Move(filePath, destPath); } }
长期优化建议
如果是生产环境使用,建议不要依赖桌面端PDF阅读器实现服务打印,可以改用无界面的PDF处理库,不需要依赖第三方软件,也不会出现会话隔离兼容性问题。
内容的提问来源于stack exchange,提问作者Ramadan Abdinour
相关产品推荐
相关产品推荐

