最近在写一个打印服务器的项目,需要获取本地打印机是否脱机的状态,上网查了一下,都是使用的下面的代码
public static int GetPrinterStatusInt(string PrinterName)
{
int intRet = 0;
IntPtr hPrinter;
PrintAPI.structPrinterDefaults defaults = new PrintAPI.structPrinterDefaults();
if (PrintAPI.OpenPrinter(PrinterName, out hPrinter, ref defaults))
{
int cbNeeded = 0;
bool bolRet = PrintAPI.GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out cbNeeded);
if (cbNeeded >= 0)
{
IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded);
bolRet = PrintAPI.GetPrinter(hPrinter, 2, pAddr, cbNeeded, out cbNeeded);
if (bolRet)
{
PrintAPI.PRINTER_INFO_2 info6 = new PrintAPI.PRINTER_INFO_2();
info6 = (PrintAPI.PRINTER_INFO_2)Marshal.PtrToStructure(pAddr, typeof(PrintAPI.PRINTER_INFO_2));
intRet = System.Convert.ToInt32(info6.Attributes);
}
Marshal.FreeHGlobal(pAddr);
}
PrintAPI.ClosePrinter(hPrinter);
}
return intRet;
}
这里有一个误区,网上的都是说使用PRINTER_INFO_2的Status字段获取打印机的状态,但是我发现这个字段没有什么用处一直都是0,反正是获取不了什么状态,最后我又仔细看了一下PRINTER_INFO_2结构中的参数,发现了Attributes这个字段,然后我调试了一下发现只要是脱机的打印机都是返回0x0000440,然后我查了一下API文档发现这个属性的几个常量如下。
#define PRINTER_ATTRIBUTE_WORK_OFFLINE 0x00000400
#define PRINTER_ATTRIBUTE_ENABLE_BIDI 0x00000800
#define PRINTER_ATTRIBUTE_RAW_ONLY 0x00001000
#define PRINTER_ATTRIBUTE_PUBLISHED 0x00002000
到这里我们只需要判断
Attributes & PRINTER_ATTRIBUTE_WORK_OFFLINE
的结果是否大于0就知道是不是脱机了。