在使用winform編寫自動打印服務的過程中,發現只要進行了打印命令的調用,文檔就會進入到打印等待隊列,如果打印機無法正常工作,則會影響到相關業務數據的正確轉換,所以需要檢查打印機的狀態來保障每次打印時打印機處於空閑狀態,打印時隊列中也只能有一個文檔,本文是通過引用System.Management來實現對打印機狀態的查詢
打印機狀態獲取
enum PrinterStatus { 其他 = 1, 未知 = 2, 空閑 = 3, 打印 = 4, 預熱 = 5, 停止打印 = 6, 脫機 = 7, } /// <summary> /// 獲取打印機的當前狀態 /// </summary> /// <param name="PrinterDevice">打印機設備名稱</param> /// <returns>打印機狀態</returns> private static PrinterStatus GetPrinterPrinterStatus(string PrinterDevice) { PrinterStatus ret = 0; string path = @"win32_printer.DeviceId='" + PrinterDevice + "'"; ManagementObject printer = new ManagementObject(path); printer.Get(); ret = (PrinterStatus)Convert.ToInt32(printer.Properties["PrinterStatus"].Value); return ret; }
打印機脫機檢查
public static bool CheckPrinter(string BindPrintName) { ManagementScope scope = new ManagementScope(@"\root\cimv2"); scope.Connect(); // Select Printers from WMI Object Collections ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Printer"); string printerName = ""; foreach (ManagementObject printer in searcher.Get()) { printerName = printer["Name"].ToString().ToLower(); if (printerName.IndexOf(BindPrintName.ToLower()) > -1) { //foreach (var property in printer.Properties) //{ // LogUtil.WriteLog(property.Name + ":" + property.Value); //} if (printer["WorkOffline"].ToString().ToLower().Equals("true")) { return false; } else { return true; } } } return false; }
打印機阻塞隊列實現
這里主要是通過一個while循環來不停的獲取打印機的狀態,空閑時才會進行下一次打印,通過兩個標志位來配合輪詢的外部介入退出
FinishWait標志位是任務內部的標識,如果打印機檢查到了錯誤狀態則進行輪詢退出
GlobalInfo.IsGlobalExist標志位是程序全局標識,如果界面上通知用戶等待時間過長,可以進行人工手動干預退出
//檢查打印機狀態 if (!CheckPrinter(PrintName)) { throw new PrintCheckException("打印機處於脫機狀態"); } PrinterStatus State = GetPrinterPrinterStatus(PrintName); if (State == PrinterStatus.空閑) { } else if (State == PrinterStatus.打印 || State == PrinterStatus.預熱) { //正在打印/預熱時循環去查詢打印機狀態,如果變成了就緒就開始打印 while (State != PrinterStatus.空閑 && !FinishWait && !GlobalInfo.IsGlobalExist) { State = GetPrinterPrinterStatus(PrintName); if (!CheckPrinter(PrintName)) { FinishWait = true; throw new PrintCheckException("打印機處於脫機狀態"); } if (State == PrinterStatus.打印 || State == PrinterStatus.預熱 || State == PrinterStatus.空閑) { if (State == PrinterStatus.空閑) { FinishWait = true; } } else { FinishWait = true; throw new PrintCheckException("打印機狀態錯誤,當前狀態:" + State.ToString()); } }