Delphi IE11示例,OleSysErrorOLE已计划关闭系统/8150002 E

e3bfsja2  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(367)

我有一个Delphi应用程序,它可以通过在后台打开IE11中的文档并使用默认的PDF打印机打印到PDF来将HTML打印到PDF。这个过程工作得很好。
问题如下:
(例如,我想将5个HTML文档打印为PDF。)
在第一次运行时,它可以很好地处理第一个文档,但会跳过其余文档,并出现以下错误:
在Win Server 2016上:
EOleSysErrorOLE已计划关闭系统。
在Windows 10上:
系统错误OLE错误8150002E
然后我等待"iexploreiderexe"关闭,这需要几秒钟。从那时起,它处理所有文档都很好,无论文档的数量如何。
如果我很长一段时间(大约一天)不使用该应用程序,它的操作与上面相同。
它在第一次运行时跳过,然后等待几秒钟,然后我们就没事了。
我尝试使用OleVariantIWebBrowser2,但结果相同。
我用.Quit关闭对象。(见下面的代码)。我还尝试了UnassignedFree,在创建新对象之前将对象设置为Null。它们都不起作用。结果相同。
以下是我作为变通方案尝试的几个方法:

  • 如果我不使用.Quit,它工作正常,但显然不会关闭任何iexplore.exe。
  • 此外,如果我打开一个IE窗口(GUI)并将其最小化,HTML-PDF过程可以正常工作。
  • 我还尝试在应用程序启动时调用在TMainForm.FormCreate()上创建一个背景IE对象,效果也很好。当应用程序进入HTML-PDF进程时,它会创建一个新的IE背景对象(额外的"iexplore.exe"),并通过保留在FormCreate()上创建的对象来关闭它。

我想弄清楚为什么它在第一次运行时不能足够快地创建和关闭对象(没有打开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;
`

我怀疑这与IE对象处理有关,但我不确定,因此在这里寻求帮助。

rekjcdws

rekjcdws1#

浏览器的Navigate()方法是异步的。您应该等待文档加载完成 * 之后 * 才能调用ExecWB()打印文档,而不是 * 之后 * 调用它。

相关问题