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:
The other offline state flags locations are:
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.