尝试确定打印机状态总是返回 0 表示离线 &在线打印机

2021-12-28 00:00:00 windows printing winapi c++ windows-shell

我的目标是确定打印机的当前状态.我找到了

像这样:

int status = GetPrinterStatus("POS58");

我收到的状态是0,和我调用功能打印机的时候完全一样

然后我尝试用

仅供参考,这里是此属性在 Windows 10 中不同位置显示的状态字符串:

  • 在打印管理中(以及您的打印窗口)-离线"
  • 带有状态的设备和打印机详细信息视图 - ""(空字符串)
  • 设备和打印机"中的查看正在打印的内容"窗口 -脱机使用打印机"

其他离线状态标志位置是:

  • PRINTER_STATUS_OFFLINE - 您对打印机信息状态的期望
  • JOB_STATUS_OFFLINE - 处于作业状态(通常是当前的打印作业)

请注意,每台打印机的确切状态行为取决于驱动程序,因为驱动程序可以设置它喜欢的任何状态.例如,我不记得看到网络打印机使用 PRINTER_ATTRIBUTE_WORK_OFFLINE,但我最近看到 Epson 收据打印机使用 PRINTER_STATUS_NOT_AVAILABLE.

My goal is to determine the current status of a printer. I found the following code. Here's a slightly modified version to fix memory leaks & bugs:

#include <Winspool.h>

int GetPrinterStatus( char* szPrnName )
{
  HANDLE          hHandle = 0;   // Handle of the printer

  DWORD           dwStatus = 0;  // Printer status we should receive

  DWORD           dwSize = 0;    // Size of memory we should
                                 // allocate for PRINTER_INFO_2

  PRINTER_INFO_2* pPrnInfo2 = 0; // Structure specifies detailed
                                 // printer information

  DEVMODE         DevMode = {0}; // Structure contains information
                                 // about the device initialization
                                 // and environment of a printer

  PRINTER_DEFAULTS PrnDef = { 0, &DevMode, PRINTER_ACCESS_USE };

  // Open printer with name szPrnName
  if( !OpenPrinter( szPrnName, &hHandle, &PrnDef ) )
    return -1; // Error

  // How many memory should be allocated for printer data?
  GetPrinter( hHandle, 2, 0, 0, &dwSize );
  if( !dwSize )
  {
    ClosePrinter( hHandle );
    return -1; // Error
  }

  // Allocate memory
  pPrnInfo2 = (PRINTER_INFO_2*)malloc( dwSize );

  // Receive printer details
  if(!GetPrinter( hHandle, 2, (LPBYTE)pPrnInfo2, dwSize, &dwSize ))
  {
    ClosePrinter( hHandle );
    free( pPrnInfo2 );
    return -1; // Error
  }

  dwStatus = pPrnInfo2->Status;

  // Free allocated memory
  free( pPrnInfo2 );

  // Close printer
  ClosePrinter( hHandle );

  return dwStatus;
}

So when I run it for this printer, that is offline:

Like this:

int status = GetPrinterStatus("POS58");

The status I receive is 0, which is exactly the same as when I call it for a functional printer

I then tried replacing OpenPrinter call with OpenPrinter2W and use PRINTER_OPTION_NO_CACHE option, but it didn't help.

What am I doing wrong?

解决方案

This Offline state (yes, there is more than one) is not actually stored as a status bit but as the PRINTER_ATTRIBUTE_WORK_OFFLINE bit in pPrnInfo2->Attributes. See this KB article.

It's set by the USB port monitor (USBMON) for a USB printer, but can also be toggled on or off by a user in the "See what's printing" window via the "Use Printer Offline" menu option:

FYI, here is the status string this attribute shows in various places in Windows 10:

  • In Print Management (and also your Print window) - "Offline"
  • Devices and Printers details view with status - "" (empty string)
  • "See what's printing" window from Devices and Printers - "Use Printer Offline"

The other offline state flags locations are:

  • PRINTER_STATUS_OFFLINE - What you were expecting in the printer info status
  • JOB_STATUS_OFFLINE - In a job status (usually the currently printing job)

Note the exact status behaviour for each printer is driver-dependent because the driver can set whatever status it likes. For instance I don't recall seeing a network printer use PRINTER_ATTRIBUTE_WORK_OFFLINE, but I recently saw an Epson receipt printer use PRINTER_STATUS_NOT_AVAILABLE.

相关文章