2011-04-18 30 views
3

我有一個已返回錯誤報告的應用程序。該應用程序使用Delphi 2006編寫,並在啓動過程中掛起。 MadExcept主線程堆棧如下所示。我懷疑沒有默認打印機,但我無法在這裏複製錯誤。Delphi TPrinters.GetPrinters調用掛起

Stack dump from 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 
+0

您需要向我們展示源代碼,否則我們將無法爲您提供幫助。 – 2011-04-18 00:46:52

+0

你在使用什麼操作系統? – 2011-04-18 01:15:49

+0

@ 0A0D不知道 - 我沒有得到調試報告,只有一個屏幕轉儲。 @Rafael - 我添加了發生掛起的單元的初始化部分。 – rossmcm 2011-04-18 01:20:44

回答

7

我不認爲這有什麼不妥程序或任何你可能會改變,使這個不掛。使用該系統的操作系統級別有問題。

NdrClientCall2函數是遠程過程調用網絡數據表示引擎的一部分,用於進行RPC和DCOM調用。

NtConnectPort是一個連接端口對象(即基本的內核對象,例如互斥鎖或文件句柄)的函數。 LPC使用最低級別的窗口使用端口。

對NtConnectPort的調用將阻塞,直到服務器調用NtCompleteConnectPort(對於調用NtConnectPort沒有超時處理)。

所以你的問題是,winspool.drv試圖建立一個LPC連接到另一個進程在同一臺機器上(我的猜測是spoolsv.exe,打印機後臺處理程序服務,但它不可能從所提供的信息)和這個其他進程已經創建了一個端口(NtCreatePort),但是它沒有調用NtListenPort,或者當NtListenPort返回時它沒有調用NtAcceptConnectPort和NtCompleteConnectPort。這可以防止每次返回時在您的進程中調用NtConnectPort。

所以真正的問題是在你的過程之外,在任何過程中,港口的另一邊屬於。