Delphi IE11 instance, OleSysErrorOLE A system shutdown has already been scheduled/8150002E

94 Views Asked by At

I have a Delphi app which prints HTML to PDF by opening the document in IE11 in the background and using the default PDF printer to print to PDF. This process works fine.

The issue is the following:

(Example I want to print 5 HTML documents to PDF.)

On the first run, it processes the first document fine, but then skips the rest with the following errors:

On Win Server 2016:

EOleSysErrorOLE A system shutdown has already been scheduled.

On Windows 10:

EOleSysErrorOLE error 8150002E

Then I wait until "iexplore.exe" closes, which takes a few sec. From then, it processes all documents just fine regardless the number of the documents.

If I do not use the app for a long time (approx a day), it does the same as above.

It skips on the first run, then waits a few seconds and then us fine.

I tried to use OleVariant and IWebBrowser2, but both have the same outcome.

I close the Object with .Quit. (see in code below). I also tried Unassigned, Free, setting the Object to Null before creating a new object. None of them worked. Same outcome.

Here are a few thing which I tried as a workaround:

  • If I do not use .Quit, it works fine, but obviously won't close any iexplore.exe.

  • Also, if I open an IE window (GUI) and minimize it, the HTML-PDF process works fine.

  • I also tried to call to create a background IE object on TMainForm.FormCreate() when the app starts, and it works as well. When it gets to the HTML-PDF process, it creates a new IE background object (additional "iexplore.exe") and closes it by leaving the one created on FormCreate().

I would like to figure out why it just cannot create and close an object fast enough on the first run (without having an IE opened or without using .Quit).

Here is the code:

Note: The program also writes some stuff to the registry, but I cut some lines for simplicity (I also might cut a few end here and there. Note that the function works fine apart than the issue above).

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;
`

I suspect that it has something do do with the IE object handling, but I'm not sure, hence asking for help here.

1

There are 1 best solutions below

2
Remy Lebeau On

The browser's Navigate() method is asynchronous. You should wait for the document to finish loading before you then call ExecWB() to print the document, not after calling it.