Windows服务启动报错1053,静默打印PDF功能不生效如何解决
问题根因分析
- 1053报错直接原因:
OnStart方法内直接写了无限while(true)循环,Windows服务要求OnStart必须在30秒内向服务控制管理器返回启动成功信号,否则会被系统判定为启动失败触发1053错误。 - 打印功能失效原因:
- 路径逻辑冲突:
Print方法遍历的是C:\A目录的文件,但MoveFile方法仅处理C:\fold目录下的文件,遍历和移动的路径不统一,不仅打印后移动逻辑不生效,本身路径不对也会导致操作异常。 - 服务会话隔离限制:Windows服务默认运行在无交互权限的Session 0,没有关联的默认打印机配置,调用
Process.Start唤起系统打印进程的方式在Session 0中无法正常执行,就算进程启动也拿不到打印机配置,打印自然失败。
- 路径逻辑冲突:
- 额外隐患:现有循环未加休眠逻辑,会无限制高频遍历目录,占用大量CPU资源,就算服务侥幸启动也会导致系统卡顿。
修复方案
第一步:改造启动逻辑解决1053报错
把循环逻辑放到独立后台线程运行,不要阻塞OnStart返回,同时增加线程退出控制:
public partial class Service1 : ServiceBase { // 新增类成员变量控制工作线程 private Thread _workThread; private volatile bool _isRunning = false; public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { _isRunning = true; // 把业务逻辑放到后台线程执行 _workThread = new Thread(DoWork); _workThread.IsBackground = true; _workThread.Start(); // 直接返回告知服务控制管理器启动成功,不会触发超时 } // 新增工作方法执行打印扫描逻辑 private void DoWork() { while (_isRunning) { try { Print(); } catch (Exception ex) { File.AppendAllText(@"C:\fold1\Log.txt", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {ex}\r\n"); } // 每次扫描后加休眠,按需调整间隔,避免CPU占用过高 Thread.Sleep(10 * 1000); } } // 改造OnStop正常退出线程 protected override void OnStop() { _isRunning = false; _workThread?.Join(5000); // 最多等待5秒让线程正常退出 File.AppendAllText(@"C:\fold1\stop.txt", "Stop method"); } // 剩余Print、MoveFile方法见后续改造 }
第二步:修复路径逻辑错误
统一文件操作路径,去掉冗余的目录遍历逻辑,仅在打印成功后移动文件:
public static void Print() { string sourceDir = @"C:\A"; string targetDir = @"C:\fold1"; if (!Directory.Exists(targetDir)) Directory.CreateDirectory(targetDir); DirectoryInfo sourceInfo = new DirectoryInfo(sourceDir); foreach (FileInfo fi in sourceInfo.GetFiles("*.pdf")) // 只处理PDF文件避免误操作 { if (fi.Length == 0) continue; // 打印成功才移动文件 if (PrintPdf(fi.FullName)) { string targetPath = Path.Combine(targetDir, fi.Name); if (File.Exists(targetPath)) File.Delete(targetPath); fi.MoveTo(targetPath); } } }
第三步:修复服务下PDF打印失效问题
不要依赖桌面PDF阅读器的打印进程,改用无需UI交互的PDF打印库实现打印,比如PdfiumViewer,可直接调用打印机接口,不受Session 0隔离影响:
private static bool PrintPdf(string pdfPath) { try { using (var document = PdfDocument.Load(pdfPath)) { using (var printDocument = document.CreatePrintDocument()) { // 可指定打印机名称,不填则使用系统默认打印机 // printDocument.PrinterSettings.PrinterName = "你的打印机名称"; printDocument.Print(); } } return true; } catch (Exception ex) { File.AppendAllText(@"C:\fold1\Log.txt", $"打印文件{pdfPath}失败:{ex}\r\n"); return false; } }
如果坚持使用外部进程打印,需要额外配置服务:打开服务属性→登录选项卡,勾选「允许服务与桌面交互」,同时指定配置好默认打印机的管理员用户运行服务,不要用默认的Local System账户,同时把打印等待时间从1秒调整为10秒以上,避免大文件还没打印完成就被杀进程。
第四步:校验服务配置
- 安装服务时确保
SC CREATE命令里的binpath填写服务exe的完整绝对路径,不要填相对路径。 - 给服务运行的账户开放
C:\A、C:\fold1目录的读写权限,以及对应打印机的使用权限。 - 检查服务器是否安装了服务编译时依赖的.NET Framework版本,版本不匹配也会触发1053启动超时错误。
内容的提问来源于stack exchange,提问作者Ramadan Abdinour
相关产品推荐
相关产品推荐

