Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Статус принтера


Автор: Denis 6.3.2014, 16:30
Пишу софтинку для самодельного терминала самообслуживания (бросил монетку, распечатал с флешки). Нужно мониторить статус (Замятие бумаги, закончилась бумага и пр.) USB принтера (HP 2055) для своевременного оповещения обслуживающего специалиста. Перерыл кучу материала, но идеального решения (В любой момент времени спросил - получил ответ) так и не нашел. Может всё-таки есть решение?

Автор: kami 6.3.2014, 16:41
http://msdn.microsoft.com/en-us/library/aa394363(VS.85).aspx
параметр DetectedErrorState
Проще всего заюзать что-нибудь готовое для Delphi, например - gLibWMI

Автор: Denis 11.3.2014, 14:53
Спасибо большое
З.Ы. Интересно то, что пару лет назад я уже юзал эти компоненты для программы сбора инфы о железе)))

Автор: Denis 18.9.2014, 13:39
Не хотел возвращаться к этой теме, но я так и не разобрался ни со стандартными функциями ни с библиотекой gLibWMI. Так что снова взываю к помощи. Вот код
Код

    Result := 0;
    DevName := Printer.Printers[6];
    if OpenPrinter(PChar(DevName),hPrinter,nil) then
    begin
      Count := 0;
      GetPrinter(hPrinter,6,nil,0,@Count);

      if Count > 0 then
      begin
        GetMem(PrinterInfo2,Count);
        GetPrinter(hPrinter,6,PrinterInfo2,Count,@Count);
        Result := PrinterInfo2.Status;

Результат работы которого всегда 0, независимо от состояния принтера. Пробовал получать PrinterInfo6, пробовал обращаться к разным принтерам, та же проблема. Что не так с кодом, подскажите?

Автор: CynicRus 19.9.2014, 20:20
Вот такая штука у меня работает без проблем:
Код

function GetPrinterStatus(const APrinterIndex: Integer): DWORD;
var
  APrinterHandle: THandle;
  APrinterInfo: PPrinterInfo2;
  ABytesNeeded: DWORD;

function GetPrinterHandle: THandle;
const
  PrinterDefaults: TPrinterDefaults = (pDatatype: nil; pDevMode: nil; DesiredAccess: PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER);

var
  ADevice, ADriver, APort: array [0. MAX_PATH] of Char;
  hDeviceMode: THandle;
begin
  Printer.GetPrinter(ADevice, ADriver, APort, hDeviceMode);
  if not OpenPrinter(@ ADevice, Result, @ PrinterDefaults) then
    RaiseLastOSError;
end;

begin
  Result: = 0;
  APrinterHandle: = 0;
  try
    Printer.PrinterIndex: = APrinterIndex;
    APrinterHandle: = GetPrinterHandle;
    ABytesNeeded: = 0;
    if not WinSpool.GetPrinter(APrinterHandle, 2, nil, 0, @ ABytesNeeded) then
      if Windows.GetLastError and ERROR_INSUFFICIENT_BUFFER then
      RaiseLastOSError;
    GetMem(APrinterInfo, ABytesNeeded);
    try
      if not WinSpool.GetPrinter(APrinterHandle, 2, APrinterInfo, ABytesNeeded, @ ABytesNeeded) then
        RaiseLastOSError;
      Result: = APrinterInfo ^.Status;
    finally
      FreeMem(APrinterInfo);
    end;
  except
    on E: Exception do
    begin
      if APrinterHandle <> 0 then
        ClosePrinter(APrinterHandle);
      raise;
    end;
  end;
end;     


PS: а вот мой пример, писал в том году - работает под Win 7\XP на Delphi XE3: http://codes-sources.commentcamarche.net/source/100256-surveillance-print-spooler-via-winapi

Автор: Mr_Devil 29.11.2016, 16:33
Код

uses WinSpool;

procedure GetPrinterStatus(PrinterName: string; out PrinterStatus, PrinterJobs: Cardinal);
var
  BufferLength: Cardinal;
  Buffer: Pointer;
  PrinterInfo: PPrinterInfo2;
  hPrinter: THandle;
  PD: TPrinterDefaults;
begin
  PrinterStatus := MAXDWORD;
  ZeroMemory(@PD, SizeOf(PD));
  PD.DesiredAccess := PRINTER_ACCESS_USE;
  if OpenPrinter(PChar(PrinterName), hPrinter, @PD) then
  try
    GetPrinter(hPrinter, 2, nil, 0, @BufferLength);
    if GetLastError = ERROR_INSUFFICIENT_BUFFER then
    begin
      Buffer := AllocMem(BufferLength);
      try
        if GetPrinter(hPrinter, 2, Buffer, BufferLength, @BufferLength) then
        begin
          PrinterInfo := PPrinterInfo2(Buffer);

          PrinterStatus := PrinterInfo^.Status;

          // для распознавания автономного режима
          if (PrinterInfo^.Attributes and PRINTER_ATTRIBUTE_WORK_OFFLINE) > 0 then
            PrinterStatus := PrinterStatus or PRINTER_STATUS_OFFLINE;

          PrinterJobs := PrinterInfo^.cJobs;
        end
        else
          RaiseLastOSError;
      finally
        FreeMem(Buffer, BufferLength);
      end;
    end
    else
      RaiseLastOSError;
  finally
    ClosePrinter(hPrinter);
  end;
end;


Автор: AndyL 12.7.2019, 18:40
Здравствуйте! У меня та же проблема. При подключении по usb TPrinterInfo2.Status дает всегда 0. Можно только определить отключен ли принтер по атрибуту (PRINTER_ATTRIBUTE_WORK_OFFLINE). А как определить, что в принтере нет бумаги?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)