Delphi调用IE11批量转HTML为PDF首次运行报错排查
Delphi IE11后台打印HTML转PDF的首次运行异常问题
我开发了一款Delphi应用,通过后台启动IE11加载HTML文档,使用默认PDF打印机将其转为PDF,单份文档的处理流程本身可正常运行。
问题现象
批量处理场景下(例如需转换5份HTML文档):
- 首次运行时,仅能正常处理第一份文档,后续所有文档均报错跳过:
- Windows Server 2016环境:报错信息为
EOleSysErrorOLE A system shutdown has already been scheduled. - Windows 10环境:报错信息为
EOleSysErrorOLE error 8150002E
- Windows Server 2016环境:报错信息为
- 等待
iexplore.exe进程完全关闭(需数秒)后,批量处理可恢复正常;若应用闲置约1天再次启动,会重复出现上述问题。
已尝试的排查操作
- 分别使用
OleVariant和IWebBrowser2两种方式调用IE对象,问题表现一致 - 调用
.Quit方法关闭对象,同时试过Unassigned、Free、置为Null等资源释放操作,均无法解决问题
临时可行的解决方案
- 不调用
.Quit方法时,流程可正常运行,但iexplore.exe进程会持续留存,无法自动关闭 - 打开IE图形界面窗口并最小化后,HTML转PDF的批量处理流程正常
- 在
TMainForm.FormCreate()时提前创建后台IE对象,后续处理时新建并关闭额外的IE对象,流程可正常运行
需求
希望明确为何首次运行时无法快速创建并关闭IE对象(无需提前打开IE或不调用.Quit),相关代码如下:
function THTMLMergeDocument.FilePrint: boolean; var BrowserObject: OleVariant; ie : IWebBrowser2; vaIn, vaOut: OleVariant; OldHeader, OldFooter, OldPrinterName: String; OldOrientation: Integer; Registry : TRegistry; ST, TOutVal: TDateTime; sUrl : string; Flag, TargetFrameName, PostData, Headers : OleVariant; begin result := false; try if fPrinterName = VTPrint.GetDefaultPrinter then begin try //Tried OleVariant { BrowserObject := Unassigned; BrowserObject := CreateOleObject('InternetExplorer.Application'); BrowserObject.Silent := true; BrowserObject.Visible := false; BrowserObject.Navigate('file:\'+DocumentFileName); BrowserObject.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER); while BrowserObject.Busy or BrowserObject.ReadyState <> READYSTATE_COMPLETE do begin Application.ProcessMessages; end; } //Tried IWebBrowser2 ie := CoInternetExplorer.Create; sUrl := 'file:\'+DocumentFileName; ie.Navigate(sUrl, Flag, TargetFrameName, PostData, Headers); ie.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER,vaIn,vaOut); while ie.ReadyState <> READYSTATE_COMPLETE do begin Application.ProcessMessages; end; if (PDFOutput) then begin ST := Now; TOutVal := EncodeTime(0,DocumentServerOptions.PDFConverterTimeOutInterval,0,0); while not PDF.Completed and (Now-ST<TOutVal) do Application.ProcessMessages; if PDF.Completed then result := true else WinWordLogProc('ERROR: No response received from PDF converter'); end else begin result := true; end; ie.Quit; //close IWebBrowser2 object BrowserObject.Quit; //close OleVariant object except on E: Exception do WinWordLogProc( 'Error class: ' + E.ClassName + #13 + E.Message); end; end else begin WinWordLogProc('Error setting default printer to '+fPrinterName); end; finally VTPrint.SetDefaultPrinter(OldPrinterName); end; end;
内容的提问来源于stack exchange,提问作者Bontoomester
相关产品推荐
相关产品推荐

