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

转载:http://www.cnblogs.com/JustYong/p/3861141.html

新项目中牵涉到对打印机的一些操作,最重要的莫过于获取打印机的状态,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                 @"System\CurrentControlSet\Control\Print\Monitors\Advanced Port Monitor\Ports\" + portName,
 55                 @"System\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\" + portName
 56             };
 57         }
 58 
 59         private string[] GetPortQuerys(string portName)
 60         {
 61             return new string[] 
 62             {
 63                 @"System\CurrentControlSet\Control\Print\Monitors\Advanced Port Monitor\Ports\" + portName,
 64                 @"System\CurrentControlSet\Control\Print\Monitors\Local Port\Ports\" + portName,
 65                 @"System\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\" + portName,
 66                 @"System\CurrentControlSet\Control\Print\Monitors\USB Monitor\Ports\" + portName,
 67                 @"System\CurrentControlSet\Control\Print\Monitors\WSD Port\Ports\" + 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 "\r\n"
193                 string[] retMsgs = strOutMsg.Split(new string[] { "\r\n" }, 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 "\r\n"
219                 string[] retMsgs = strOutMsg.Split(new string[] { "\r\n" }, 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     }
复制代码
posted @ 2015-09-28 19:13  跟着阿笨一起玩.NET  阅读(860)  评论(3编辑  收藏  举报