Delphi TPrinters.GetPrinters call hangs
I have an app that has returned an error report. The app is written in Delphi 2006 and hangs during startup. The MadExcept main thread stack is shown below. I suspect there is no default printer but I can't replicate the fault here.
Anyone seen this problem?
Initialization part of unit WWPrintToPrinterOrPDFRoutines
initialization
PagesRangeStartPage := 1 ;
PagesRangeEndPage := 999 ;
PrintRange := prAll ;
PrintCopies := 1 ;
PrintCollate := false ;
InitialPrintPaperName := 'A4' ;
if (Printer.Printers.Count = 0) then // <--------- this causes the hang
begin
InitialPrintOrientation := Printers.poPortrait ;
end
else
begin
InitialPrintOrientation := GetDefaultPrinterOrientation ;
InitialPrintPaperName := GetDefaultPrinterPaperName ;
end ;
CurrentPreviewPage := 1 ;
NDRMemoryStream := TMemoryStream.Create ;
or disassembled:
WWPrintToPrinterOrPDFRoutines.pas.682: PagesRangeStartPage := 1 ;
007C4404 C705EC8B81000100 mov [$00818bec],$00000001
WWPrintToPrinterOrPDFRoutines.pas.683: PagesRangeEndPage := 999 ;
007C440E C705F08B8100E703 mov [$00818bf0],$000003e7
WWPrintToPrinterOrPDFRoutines.pas.684: PrintRange := prAll ;
007C4418 C605F48B810001开发者_StackOverflow社区 mov byte ptr [$00818bf4],$01
WWPrintToPrinterOrPDFRoutines.pas.685: PrintCopies := 1 ;
007C441F C705F88B81000100 mov [$00818bf8],$00000001
WWPrintToPrinterOrPDFRoutines.pas.686: PrintCollate := false ;
007C4429 C605FC8B810000 mov byte ptr [$00818bfc],$00
WWPrintToPrinterOrPDFRoutines.pas.687: InitialPrintPaperName := 'A4' ;
007C4430 B8288C8100 mov eax,$00818c28
007C4435 BAC0447C00 mov edx,$007c44c0
007C443A E82D1AC4FF call @LStrAsg
WWPrintToPrinterOrPDFRoutines.pas.689: if (Printer.Printers.Count = 0) then
007C443F E8B0BCCDFF call Printer
007C4444 E89FB7CDFF call TPrinter.GetPrinters <----- HANG OCCURS HERE
I don't think there is anything wrong with your program or anything you could change to make this not hang. Something is wrong on the OS level with that system.
That NdrClientCall2 function is part of the Remote Procedure Call Network Data Representation Engine which is used for making RPC and DCOM calls.
NtConnectPort is a function to connect a port object (that's a fundamental kernel object, like e.g. a mutex or a file handle). Ports are used by windows at the lowest level for LPCs.
A call to NtConnectPort will block until the server called NtCompleteConnectPort (there is no timeout handling for calls to NtConnectPort).
So your problem is that winspool.drv tries to establish an LPC connection to another process on the same machine (my guess would be spoolsv.exe, the printer spooler service, but it's impossible to tell from the information provided) and this other process has created a port (NtCreatePort) but has either not called NtListenPort on it, or when NtListenPort returns does not call NtAcceptConnectPort and NtCompleteConnectPort on it. Which prevents the call to NtConnectPort in your process from every returning.
So the real problem is outside of your process, in whatever process the other side of the port belongs to.
精彩评论