【问题标题】:Delphi TPrinters.GetPrinters call hangsDelphi TPrinters.GetPrinters 调用挂起
【发布时间】:2011-04-18 00:25:45
【问题描述】:

我有一个应用程序返回了错误报告。该应用程序是用 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

【问题讨论】:

  • 您需要向我们展示源代码,否则我们将无法为您提供帮助。
  • @0A0D 不确定 - 我没有得到调试报告,只有屏幕转储。 @Rafael - 我添加了发生挂起的单元的初始化部分。
  • 当工作站的打印机列表中有网络打印机时,我会发生这种情况,该打印机指向的计算机不再存在或无法通过网络进行通信。可能是关机了,或者计算机被重命名了,或者你现在在不同的网络上。
  • 谢谢@Warren。我会将用户更改为这种可能性。
  • ...我也会提醒用户这种可能性...

标签: delphi startup freeze delphi-2006 printers


【解决方案1】:

我认为您的程序没有任何问题,或者您可以进行任何更改以使其不会挂起。该系统的操作系统级别出现问题。

NdrClientCall2 函数是远程过程调用网络数据表示引擎的一部分,用于进行 RPC 和 DCOM 调用。

NtConnectPort 是一个连接端口对象的函数(这是一个基本的内核对象,例如互斥体或文件句柄)。端口由 LPC 的最低级别的窗口使用。

对 NtConnectPort 的调用将阻塞,直到服务器调用 NtCompleteConnectPort(对 NtConnectPort 的调用没有超时处理)。

所以你的问题是 winspool.drv 试图建立与同一台机器上另一个进程的 LPC 连接(我的猜测是 spoolsv.exe,打印机后台处理程序服务,但从提供的信息中无法判断)并且这个其他进程已经创建了一个端口(NtCreatePort),但是没有调用 NtListenPort,或者当 NtListenPort 返回时没有调用 NtAcceptConnectPort 和 NtCompleteConnectPort。这可以防止每次返回时在您的进程中调用 NtConnectPort。

所以真正的问题在你的进程之外,无论端口的另一端属于什么进程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多