Delphi TPrinters.GetPrinters вызывает зависания - PullRequest
3 голосов
/ 18 апреля 2011

У меня есть приложение, которое вернуло сообщение об ошибке.Приложение написано в Delphi 2006 и зависает при запуске.Стек основного потока MadExcept показан ниже.Я подозреваю, что нет принтера по умолчанию, но я не могу повторить ошибку здесь.

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

1 Ответ

7 голосов
/ 18 апреля 2011

Я не думаю, что с вашей программой что-то не так или что-то, что вы можете изменить, чтобы это не зависало.Что-то не так на уровне ОС с этой системой.

Эта функция NdrClientCall2 является частью механизма представления данных сети удаленного вызова процедур, который используется для выполнения вызовов RPC и DCOM.

NtConnectPort - это функция для подключения объекта порта (это фундаментальный объект ядра, например, мьютекс или дескриптор файла).Порты используются окнами на самом низком уровне для LPC.

Вызов NtConnectPort будет блокироваться до тех пор, пока сервер с именем NtCompleteConnectPort (время ожидания вызовов для вызовов NtConnectPort отсутствует).

Так что ваша проблемаявляется то, что winspool.drv пытается установить соединение LPC с другим процессом на той же машине (я думаю, что это будет spoolsv.exe, служба диспетчера очереди печати, но это невозможно определить из предоставленной информации), и этот другой процесс создал порт(NtCreatePort), но либо не вызвал NtListenPort, либо, когда возвращается NtListenPort, не вызывает NtAcceptConnectPort и NtCompleteConnectPort для него.Это предотвращает каждый возврат вызова NtConnectPort в вашем процессе.

Таким образом, настоящая проблема находится за пределами вашего процесса, в любом процессе, к которому принадлежит другая сторона порта.

...