我有一个已经返回错误报告的应用程序.该应用程序是用Delphi 2006编写的,并在启动时挂起. MadExcept主线程堆栈如下所示.我怀疑没有默认打印机,但我不能在这里复制故障. 谁见过这个问题?
谁见过这个问题?
单元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 ;
或拆解:
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 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我不认为你的程序或任何你可以改变的东西没有任何问题,使这不挂起.该系统在操作系统级别出现问题.
NdrClientCall2函数是远程过程调用网络数据表示引擎的一部分,用于进行RPC和DCOM调用.
NtConnectPort是一个连接端口对象的函数(这是一个基本的内核对象,例如互斥锁或文件句柄). LPC最低级别的窗口使用端口.
对NtConnectPort的调用将阻塞,直到服务器调用NtCompleteConnectPort(对NtConnectPort的调用没有超时处理).
所以你的问题是winspool.drv试图建立一个LPC连接到同一台机器上的另一个进程(我的猜测是spoolsv.exe,打印机后台处理程序服务,但是从提供的信息中无法判断)这个其他进程有创建了一个端口(NtCreatePort)但是没有在其上调用NtListenPort,或者当NtListenPort返回时没有调用NtAcceptConnectPort和NtCompleteConnectPort.这会阻止您的流程中每次返回时对NtConnectPort的调用.
所以真正的问题是在你的进程之外,无论在端口的另一端属于什么进程.