VB.Net调用Word打印特定信函时特定打印机任务自动取消问题
问题描述
【编辑补充】该问题已通过优化后台打印处理逻辑修复,关联解决方案提供了持续休眠直至后台任务执行完成的实现方法。
我司现有一款已服役15年以上的VB6程序,承担信函打印、SQL记录更新等功能,信函内容通过Bookmarks关联SQL数据自动填充。目前我负责将该程序重构为VB.Net版本,整体开发进展顺利,仅遇到特定打印机无法打印指定8.5×14尺寸信函的异常:
- 代码可正常打印其他尺寸信函、适配其他打印机,该目标文档直接通过Word、PDF手动打印也完全正常;
- 代码运行时可正常打开对应Word文档供用户修改,在弹出的Word窗口中手动点击打印也可正常输出,仅调用PrintOut方法自动打印时异常:打印任务进入假脱机状态后直接取消,不会进入实际打印环节。
现有打印相关代码如下:
goWord.Visible = True MsgBox("Click OK when finished making changes.") goWord.WordBasic.fileprintsetup(Printer:=strLetterPrinter, DoNotSetAsSysDefault:=1) If intTraySelection <> 0 Then goWord.ActiveDocument.PageSetup.FirstPageTray = intTraySelection Else goWord.ActiveDocument.PageSetup.FirstPageTray = 261 End If goWord.ActiveDocument.PrintOut() System.Threading.Thread.Sleep(500) odoc.Close(False) odoc = Nothing goWord.Quit(False) odoc = Nothing goWord = Nothing
其中intTraySelection参数取值沿用自可正常打印的旧VB6代码,取值逻辑如下:
If rdbTray1.Checked = True Then intTraySelection = 258 ElseIf rdbTray2.Checked = True Then intTraySelection = 260 ElseIf rdbTray3.Checked = True Then intTraySelection = 259 ElseIf rdbTray4.Checked = True Then intTraySelection = 257 Else intTraySelection = 261 End If
我查询不到上述进纸托盘编号的相关说明,且即使不设置FirstPageTray属性,问题也会复现。麻烦各位帮忙排查问题原因。
排查与解决方案
根因定位
你当前代码的核心问题是固定500ms休眠后就直接关闭文档、退出Word进程。8.5×14尺寸的信函数据量比普通A4/Letter尺寸更大,目标打印机的假脱机响应速度慢,500ms的等待时间不足以让打印任务完全提交到打印机队列,Word进程提前退出就会直接终止未完成的打印任务,这也是手动操作打印正常、自动调用PrintOut异常的直接原因。
修复方案
- 替换固定休眠逻辑,优先使用Word PrintOut的同步打印参数
Word的PrintOut方法支持Background参数,设置为False时代码会阻塞等待打印任务完全提交完成后再继续执行,兼容性远高于固定时长休眠。 - 显式指定打印纸张尺寸,避免自动识别异常
8.5×14属于标准Legal纸张,可显式设置文档的纸张尺寸属性,避免部分老旧打印机驱动识别自定义尺寸出错。 - 可选优化:如果业务要求必须使用异步打印,可以增加打印队列状态监听逻辑,循环判断当前文档的打印任务是否完成,再执行关闭Word的操作。
修复后参考代码
goWord.Visible = True MsgBox("Click OK when finished making changes.") goWord.WordBasic.fileprintsetup(Printer:=strLetterPrinter, DoNotSetAsSysDefault:=1) ' 显式设置Legal尺寸(8.5×14),避免尺寸识别异常 goWord.ActiveDocument.PageSetup.PaperSize = Microsoft.Office.Interop.Word.WdPaperSize.wdPaperLegal If intTraySelection <> 0 Then goWord.ActiveDocument.PageSetup.FirstPageTray = intTraySelection Else goWord.ActiveDocument.PageSetup.FirstPageTray = 261 End If ' Background参数设为False,同步等待打印提交完成再往下执行 goWord.ActiveDocument.PrintOut(Background:=False) ' 若仍有偶发失败,可以额外加100-200ms缓冲,无需太长 System.Threading.Thread.Sleep(200) odoc.Close(False) odoc = Nothing goWord.Quit(False) odoc = Nothing goWord = Nothing
补充说明
你提到的进纸托盘编号无公开说明是正常情况,这类编号是打印机厂商自定义的数值,不同品牌、型号的打印机托盘ID完全不通用。你已验证不设置该属性仍复现问题,可以暂时排除该参数的影响,先完成打印等待逻辑的修复。
内容的提问来源于stack exchange,提问作者Daniel Long
相关产品推荐
相关产品推荐

