.Net中获取打印机的相关信息

新项目中牵涉到对打印机的一些操作,最重要的莫过于获取打印机的状态,IP等信息,代码量不大,但是也是自己花了一点时间总结出来的,希望能帮助需要的朋友。

PrinterCommunicate用于连接打印机并发送指令

 1     public class PrinterCommunicate
 2     {
 3 
 4         public bool CheckNetWorkConnection(string strPrinterIP, int intPrinterPort) 
 5         {
 6            System.Net.Sockets.TcpClient Zebraclient = new TcpClient();
 7            try
 8            {
 9                Zebraclient.Connect(strPrinterIP, intPrinterPort);
10                return Zebraclient.Connected;
11            }
12            catch
13            {
14                return false;
15            }
16         }
17 
18         public bool SendZPL_ViaNetwork(string strPrinterIP, int intPrinterPort, string strPrinterCommand, out string strOutMsg)
19         {
20             strOutMsg = "";
21 
22             System.Net.Sockets.TcpClient Zebraclient = new TcpClient();
23             try
24             {
25                 Zebraclient.SendTimeout = 1500;
26                 Zebraclient.ReceiveTimeout = 1500;
27                 //defining ip address and port number
28                 Zebraclient.Connect(strPrinterIP, intPrinterPort);
29 
30                 if (Zebraclient.Connected == true)
31                 {
32                     //send and receive illustrated below
33                     NetworkStream mynetworkstream;
34                     StreamReader mystreamreader;
35                     StreamWriter mystreamwriter;
36                     mynetworkstream = Zebraclient.GetStream();
37                     mystreamreader = new StreamReader(mynetworkstream);
38                     mystreamwriter = new StreamWriter(mynetworkstream);
39 
40                     mystreamwriter.WriteLine(strPrinterCommand);
41                     mystreamwriter.Flush();
42                     char[] mk = null;
43                     mk = new char[256];
44                     mystreamreader.Read(mk, 0, mk.Length);
45                     string data1 = new string(mk);
46                     strOutMsg = data1;
47                     Zebraclient.Close();
48 
49                     return true;
50                 }
51                 else
52                 {
53                     strOutMsg = "Connection failed";
54                     return false;
55                 }
56             }
57             catch (Exception ex)
58             {
59                 Log.WriteLogToFile("IPP_PCL", "PrinterCommunicate.cs -- SendZPL_ViaNetwork", "-99", ex.Message);
60                 strOutMsg = "EXCEPTION_ERROR";
61             }
62 
63             return false;
64         }
65 
66     }

WindowsPrintQueue用于获取打印机的型号,以及得到打印机的WindowsPrintQueue

  1     public class WindowsPrintQueue
  2     {
  3         /// <summary>
  4         /// whether the two printer is same model.
  5         /// </summary>
  6         /// <param name="printerName1"></param>
  7         /// <param name="printerName2"></param>
  8         /// <returns></returns>
  9         public bool IsSameModel(string printerName1, string printerName2)
 10         {
 11             return GetPrinterModel(printerName1).Equals(GetPrinterModel(printerName2));
 12         }
 13 
 14         /// <summary>
 15         /// whether the printer is zebra model.
 16         /// </summary>
 17         /// <param name="printerName1"></param>
 18         /// <param name="printerName2"></param>
 19         /// <returns></returns>
 20         public bool IsZebraPrinter(string printerName)
 21         {
 22             string zebraModel = "ZEBRA";
 23             return GetPrinterModel(printerName).Contains(zebraModel);
 24         }
 25 
 26         /// <summary>
 27         /// Return printer model
 28         /// </summary>
 29         /// <param name="printerName"></param>
 30         /// <returns></returns>
 31         public string GetPrinterModel(string printerName)
 32         {
 33             string model = string.Empty;
 34             System.Printing.PrintQueue printQueue = GetPrintQueue(printerName);
 35             if (printQueue != null)
 36             {
 37                 //Get printer model
 38                 if (printQueue.Description.IndexOf(",") == printQueue.Description.LastIndexOf(","))
 39                 {
 40                     model = printQueue.Description.Substring(printQueue.Description.IndexOf(",") + 1,
printQueue.Description.LastIndexOf(",") - printQueue.Description.IndexOf(",") - 1); 41 } 42 else 43 { 44 model = printQueue.Description.Substring(printQueue.Description.IndexOf(",") + 1); 45 } 46 } 47 return model; 48 } 49 50 /// <summary> 51 /// Get Windows Print Queue via printer name 52 /// </summary> 53 /// <param name="printerName"></param> 54 /// <returns></returns> 55 public System.Printing.PrintQueue GetPrintQueue(string printerName) 56 { 57 System.Printing.PrintQueue printQueue = null; 58 PrintServer server = new PrintServer(printerName); 59 foreach (System.Printing.PrintQueue pq in server.GetPrintQueues()) 60 { 61 if (pq.FullName.Equals(printerName)) 62 { 63 printQueue = pq; 64 } 65 } 66 return printQueue; 67 } 68 69 /// <summary> 70 /// Get Windows Print Queue via printer name 71 /// 如果两个printer指向的是同一个物理打印机,则如果copy1的printQueue已经打开,
///则发送到copy2的打印job也会添加到已经打开的copy1的printQueue中.
72 /// </summary> 73 /// <param name="printerName"></param> 74 /// <returns></returns> 75 public System.Printing.PrintQueue GetOpenedPrintQueueOfSameModel(string printerName) 76 { 77 System.Printing.PrintQueue doorOpenedprintQueue = null; 78 System.Printing.PrintQueue currentPrinterPrintQueue = null; 79 PrintServer server = new PrintServer(printerName); 80 foreach (System.Printing.PrintQueue pq in server.GetPrintQueues()) 81 { 82 if (pq.FullName.Equals(printerName)) 83 { 84 currentPrinterPrintQueue = pq; 85 } 86 else 87 { 88 if (IsSameModel(printerName, pq.FullName)) 89 { 90 if (pq.IsDoorOpened) 91 { 92 doorOpenedprintQueue = pq; 93 break; 94 } 95 } 96 } 97 } 98 99 if (doorOpenedprintQueue != null) 100 { 101 return doorOpenedprintQueue; 102 } 103 else 104 { 105 return currentPrinterPrintQueue; 106 } 107 } 108 }

PrinterPropertyManager用于管理打印机的状态以及查询修改打印机属性

  1     class PrinterPropertyManager
  2     {
  3         /// <summary>
  4         /// 获取打印机的IP地址和端口号
  5         /// </summary>
  6         /// <param name="printerName">打印机名称</param>
  8         public KeyValuePair<string, int> GetPrinterIPAndPort(string printerName)
  9         {
 10             string port = GetPrinterPropertyValue(printerName, "PortName");
 11             //Query portName's property from regedit
 12             string[] portQuerys = GetPortQuerys(port);
 13             foreach (var portQuery in portQuerys)
 14             {
 15                 RegistryKey portKey = Registry.LocalMachine.OpenSubKey(portQuery, RegistryKeyPermissionCheck.Default, 
System.Security.AccessControl.RegistryRights.QueryValues);
16 if (portKey != null) 17 {
                        /*             
            * 取IP的时候要特别注意,如果端口类型为"Advanced Port Monitor",那么IP地址会保存到IPAddress属性中                        
* 如果端口类型为"Standard Tcp/Ip Port",那么IP地址会保存到HostName属性中。
*/
18 object IPValue = portKey.GetValue("IPAddress", String.Empty,
RegistryValueOptions.DoNotExpandEnvironmentNames);
19 object portValue = portKey.GetValue("PortNumber", String.Empty,
RegistryValueOptions.DoNotExpandEnvironmentNames);
20 if (IPValue != null && portValue != null) 21 { 22 return new KeyValuePair<string, int>(IPValue.ToString(), (Int32)portValue); 23 } 24 } 25 } 26 return new KeyValuePair<string, int>(); 27 } 28 29 /// <summary> 30 /// determine whether the printer is network printer. 31 /// </summary> 34 public bool IsNetWorkPrinter(string printer) 35 { 36 string port = GetPrinterPropertyValue(printer, "PortName"); 37 //Query portName's property from regedit 38 string[] portQuerys = GetNetWorkPortQuerys(port); 39 foreach (var portQuery in portQuerys) 40 { 41 RegistryKey portKey = Registry.LocalMachine.OpenSubKey(portQuery, RegistryKeyPermissionCheck.Default,
System.Security.AccessControl.RegistryRights.QueryValues);
42 if (portKey != null) 43 { 44 return true; 45 } 46 } 47 return false; 48 } 49 50 private string[] GetNetWorkPortQuerys(string portName) 51 { 52 return new string[] 53 { 54 @"SystemCurrentControlSetControlPrintMonitorsAdvanced Port MonitorPorts" + portName, 55 @"SystemCurrentControlSetControlPrintMonitorsStandard TCP/IP PortPorts" + portName 56 }; 57 } 58 59 private string[] GetPortQuerys(string portName) 60 { 61 return new string[] 62 { 63 @"SystemCurrentControlSetControlPrintMonitorsAdvanced Port MonitorPorts" + portName, 64 @"SystemCurrentControlSetControlPrintMonitorsLocal PortPorts" + portName, 65 @"SystemCurrentControlSetControlPrintMonitorsStandard TCP/IP PortPorts" + portName, 66 @"SystemCurrentControlSetControlPrintMonitorsUSB MonitorPorts" + portName, 67 @"SystemCurrentControlSetControlPrintMonitorsWSD PortPorts" + portName, 68 }; 69 } 70 71 /// <summary> 72 /// get printer property value
/// 使用WMI查询打印机的信息,需要打开windows management instrumentation服务
73 /// </summary> 77 public string GetPrinterPropertyValue(string printerName, string propertyName) 78 { 79 80 string propertyValue = string.Empty; 81 //Query printer's portName from WIN32_Printer 82 string query = string.Format("SELECT * from Win32_Printer WHERE Name = '{0}'", printerName); 83 ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); 84 ManagementObjectCollection managementObjects = searcher.Get(); 85 foreach (ManagementObject managementObject in managementObjects) 86 { 87 PropertyData propertyData = managementObject.Properties[propertyName]; 88 if (propertyData != null) 89 { 90 propertyValue = propertyData.Value.ToString(); 91 } 92 } 93 return propertyValue; 94 } 95 96 /// <summary> 97 /// change printer property value 98 /// </summary> 102 public void SetPrinterPropertyValue(string printerName, string propertyName, string propertyValue) 103 { 104 105 //Query printer's portName from WIN32_Printer 106 string query = string.Format("SELECT * from Win32_Printer WHERE Name = '{0}'", printerName); 107 ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); 108 ManagementObjectCollection managementObjects = searcher.Get(); 109 foreach (ManagementObject managementObject in managementObjects) 110 { 111 PropertyData propertyData = managementObject.Properties[propertyName]; 112 if (propertyData != null) 113 { 114 propertyData.Value = propertyValue; 115 managementObject.Put(); 116 } 117 } 118 }

 /// <summary>
        /// whether the port is existed
/// 检查某个打印端口是否存在
        /// </summary>
        /// <param name="printerName"></param>
        /// <param name="port"></param>
        /// <returns></returns>
        public bool IsPortExisted(string printerName,string port)
        {
            string propertyName = "PortName";
            string currentPort = null;
            try
            {
                currentPort = GetPrinterPropertyValue(printerName, propertyName);
                SetPrinterPropertyValue(printerName, propertyName, port);
                SetPrinterPropertyValue(printerName, propertyName, currentPort);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
119 120 /// <summary> 121 /// 获取打印机名字的列表 122 /// </summary> 124 public ArrayList GetPrinterNames() 125 { 126 ArrayList result = new ArrayList(); 127 128 foreach (string ss in PrinterSettings.InstalledPrinters) 129 { 130 result.Add(ss); 131 } 132 return result; 133 } 134 135 /// <summary> 136 /// 获取打印机状态 137 /// </summary> 138 /// <param name="printerName">打印机名称</param> 140 public PrinterStatus GetPrinterStatus(string printerName,out bool isError,out string errorDescription) 141 { 142 //init return variable 143 isError = false; 144 errorDescription = string.Empty; 145 PrinterStatus printerStatus = PrinterStatus.Idle; 146 if (IsNetWorkPrinter(printerName)) 147 { 148 KeyValuePair<string, int> ipPortKeyValuePair = GetPrinterIPAndPort(printerName); 149 PrinterCommunicate printerCommunicate = new PrinterCommunicate(); 150 if (printerCommunicate.CheckNetWorkConnection(ipPortKeyValuePair.Key, ipPortKeyValuePair.Value)) 151 { 152 WindowsPrintQueue winowsPrintQueue = new WindowsPrintQueue(); 153 if (winowsPrintQueue.IsZebraPrinter(printerName)) 154 { 155 //get actual status of zebra printer via zebra command 156 if(IsPause(ipPortKeyValuePair.Key, ipPortKeyValuePair.Value)) 157 { 158 printerStatus = PrinterStatus.Paused; 159 } 160 161 string errorMsg = string.Empty; 162 if(IsError(ipPortKeyValuePair.Key, ipPortKeyValuePair.Value, out errorMsg)) 163 { 164 isError = true; 165 errorDescription = GetZebraPrinterErrorStatusDescription(errorMsg); 166 } 167 } 168 } 169 else 170 { 171 //not connected 172 printerStatus = PrinterStatus.Offline; 173 } 174 } 175 return printerStatus; 176 } 177 178 /// <summary> 179 /// determine whether the network printer is in pause.Only for zebra model printer 180 /// </summary> 185 private bool IsPause(string ip, int port) 186 { 187 string strOutMsg = null; 188 string zebraCommand = "^XA~HS^XZ"; 189 PrinterCommunicate printerCommunicate = new PrinterCommunicate(); 190 if (printerCommunicate.SendZPL_ViaNetwork(ip, port, zebraCommand, out strOutMsg)) 191 { 192 //split retMsg with " " 193 string[] retMsgs = strOutMsg.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); 194 if (retMsgs != null) 195 { 196 string retFirstMsgItem = retMsgs[0]; 197 string[] retFirstMsgItems = retFirstMsgItem.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); 198 return "1".Equals(retFirstMsgItems[2]); 199 } 200 } 201 return false; 202 } 203 204 /// <summary> 205 /// determine whether the network printer is in error.only for zebra model printer 206 /// </summary> 207 /// <param name="ip"></param> 208 /// <param name="port"></param> 209 /// <param name="strOutMsg"></param> 210 /// <returns></returns> 211 private bool IsError(string ip, int port, out string strOutMsg) 212 { 213 strOutMsg = string.Empty; 214 string zebraCommand = "^XA~HQES^XZ"; 215 PrinterCommunicate printerCommunicate = new PrinterCommunicate(); 216 if (printerCommunicate.SendZPL_ViaNetwork(ip, port, zebraCommand, out strOutMsg)) 217 { 218 //split retMsg with " " 219 string[] retMsgs = strOutMsg.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); 220 if (retMsgs != null) 221 { 222 for (int i = 0; i < retMsgs.Length; i++) 223 { 224 string retMsgItem = retMsgs[i]; 225 if (string.IsNullOrEmpty(retMsgItem) || !retMsgItem.Contains(":")) { continue; } 226 227 string[] retMsgItemSplited = retMsgItem.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries); 228 if (retMsgItemSplited == null || retMsgItemSplited.Length == 0) { continue; } 229 230 string errorMsg = retMsgItemSplited[1].Trim(); 231 if (!string.IsNullOrEmpty(errorMsg)) 232 { 233 string errorFlag = errorMsg.Substring(0, 1); 234 if ("1".Equals(errorFlag)) 235 { 236 strOutMsg = errorMsg; 237 return true; 238 } 239 } 240 } 241 } 242 } 243 return false; 244 } 245 246 /// <summary> 247 /// get actual status of zebra printer via zebra command. 248 /// </summary> 249 /// <param name="ip"></param> 250 /// <param name="port"></param> 251 /// <returns></returns> 252 private string GetZebraPrinterErrorStatusDescription(string errorMsg) 253 { 254 StringBuilder status = new StringBuilder(); 255 //error happend 256 string nibble1 = errorMsg.Substring(errorMsg.Length - 1, 1); 257 string nibble2 = errorMsg.Substring(errorMsg.Length - 2, 1); 258 string nibble3 = errorMsg.Substring(errorMsg.Length - 3, 1); 259 260 if (!"0".Equals(nibble1)) 261 { 262 Dictionary<int, string> nibble1ErrorDictionary = new Dictionary<int, string>(); 263 nibble1ErrorDictionary.Add(1, "Midea Out"); 264 nibble1ErrorDictionary.Add(2, "Ribbon Out"); 265 nibble1ErrorDictionary.Add(4, "Head Open"); 266 nibble1ErrorDictionary.Add(8, "Cutter Fault"); 267 268 status.Append(GetErrorDescriptionFromNibble(nibble1, nibble1ErrorDictionary)); 269 } 270 271 if (!"0".Equals(nibble2)) 272 { 273 Dictionary<int, string> nibble2ErrorDictionary = new Dictionary<int, string>(); 274 nibble2ErrorDictionary.Add(1, "Printhead Over Temperature"); 275 nibble2ErrorDictionary.Add(2, "Motor Over Temperature"); 276 nibble2ErrorDictionary.Add(4, "Bad Printhead Element"); 277 nibble2ErrorDictionary.Add(8, "Printhead Detection Error"); 278 279 status.Append(GetErrorDescriptionFromNibble(nibble1, nibble2ErrorDictionary)); 280 } 281 282 if (!"0".Equals(nibble3)) 283 { 284 Dictionary<int, string> nibble3ErrorDictionary = new Dictionary<int, string>(); 285 nibble3ErrorDictionary.Add(1, "Invalid Firmware Config"); 286 nibble3ErrorDictionary.Add(2, "Printhead Thermistor Open"); 287 288 status.Append(GetErrorDescriptionFromNibble(nibble1, nibble3ErrorDictionary)); 289 } 290 291 string strStatus = status.ToString(); 292 return strStatus.Substring(0, strStatus.Length - 1); 293 } 294 295 private StringBuilder GetErrorDescriptionFromNibble(string nibble, Dictionary<int, string> statusDictionary) 296 { 297 int intNibble = Convert.ToInt32(nibble); 298 StringBuilder status = new StringBuilder(); 299 if (statusDictionary != null) 300 { 301 foreach (var statusKV in statusDictionary) 302 { 303 if ((intNibble & statusKV.Key) == statusKV.Key) 304 { 305 status.Append(statusKV.Value); 306 status.Append(","); 307 } 308 } 309 } 310 return status; 311 } 312 } 313 314 315 316 public enum PrinterStatus 317 { 318 Other = 1, 319 Unknown = 2, 320 Idle = 3, 321 Printing = 4, 322 Warmup = 5, 323 Paused = 6, 324 Offline = 7 325 }

 获取已安装的打印机驱动

 public IEnumerable<string> GetPrintDrivers()
        {
            var dirvers = new List<string>();
            //Query printer's portName from WIN32_Printer
            string query = string.Format("SELECT * from Win32_PrinterDriver");

            var searcher = new ManagementObjectSearcher(query);

            ManagementObjectCollection managementObjects = searcher.Get();

            foreach (ManagementObject managementObject in managementObjects)
            {
                var name = managementObject.Properties["Name"].Value;

                dirvers.Add(name.ToString());
            }

            return dirvers;
        }
原文地址:https://www.cnblogs.com/JustYong/p/3861141.html