新项目中牵涉到对打印机的一些操作,最重要的莫过于获取打印机的状态,IP等信息,代码量不大,但是也是自己花了一点时间总结出来的,希望能帮助需要的朋友。
PrinterCommunicate用于连接打印机并发送指令
1 public class PrinterCommunicate
{ public bool CheckNetWorkConnection(string strPrinterIP, int intPrinterPort)
{
System.Net.Sockets.TcpClient Zebraclient = new TcpClient();
try
{
Zebraclient.Connect(strPrinterIP, intPrinterPort);
return Zebraclient.Connected;
}
catch
{
return false;
}
} public bool SendZPL_ViaNetwork(string strPrinterIP, int intPrinterPort, string strPrinterCommand, out string strOutMsg)
{
strOutMsg = ""; System.Net.Sockets.TcpClient Zebraclient = new TcpClient();
try
{
Zebraclient.SendTimeout = ;
Zebraclient.ReceiveTimeout = ;
//defining ip address and port number
Zebraclient.Connect(strPrinterIP, intPrinterPort); if (Zebraclient.Connected == true)
{
//send and receive illustrated below
NetworkStream mynetworkstream;
StreamReader mystreamreader;
StreamWriter mystreamwriter;
mynetworkstream = Zebraclient.GetStream();
mystreamreader = new StreamReader(mynetworkstream);
mystreamwriter = new StreamWriter(mynetworkstream); mystreamwriter.WriteLine(strPrinterCommand);
mystreamwriter.Flush();
char[] mk = null;
mk = new char[];
mystreamreader.Read(mk, , mk.Length);
string data1 = new string(mk);
strOutMsg = data1;
Zebraclient.Close(); return true;
}
else
{
strOutMsg = "Connection failed";
return false;
}
}
catch (Exception ex)
{
Log.WriteLogToFile("IPP_PCL", "PrinterCommunicate.cs -- SendZPL_ViaNetwork", "-99", ex.Message);
strOutMsg = "EXCEPTION_ERROR";
} return false;
} }
WindowsPrintQueue用于获取打印机的型号,以及得到打印机的WindowsPrintQueue
public class WindowsPrintQueue
{
/// <summary>
/// whether the two printer is same model.
/// </summary>
/// <param name="printerName1"></param>
/// <param name="printerName2"></param>
/// <returns></returns>
public bool IsSameModel(string printerName1, string printerName2)
{
return GetPrinterModel(printerName1).Equals(GetPrinterModel(printerName2));
} /// <summary>
/// whether the printer is zebra model.
/// </summary>
/// <param name="printerName1"></param>
/// <param name="printerName2"></param>
/// <returns></returns>
public bool IsZebraPrinter(string printerName)
{
string zebraModel = "ZEBRA";
return GetPrinterModel(printerName).Contains(zebraModel);
} /// <summary>
/// Return printer model
/// </summary>
/// <param name="printerName"></param>
/// <returns></returns>
public string GetPrinterModel(string printerName)
{
string model = string.Empty;
System.Printing.PrintQueue printQueue = GetPrintQueue(printerName);
if (printQueue != null)
{
//Get printer model
if (printQueue.Description.IndexOf(",") == printQueue.Description.LastIndexOf(","))
{
model = printQueue.Description.Substring(printQueue.Description.IndexOf(",") + ,
printQueue.Description.LastIndexOf(",") - printQueue.Description.IndexOf(",") - );
}
else
{
model = printQueue.Description.Substring(printQueue.Description.IndexOf(",") + );
}
}
return model;
} /// <summary>
/// Get Windows Print Queue via printer name
/// </summary>
/// <param name="printerName"></param>
/// <returns></returns>
public System.Printing.PrintQueue GetPrintQueue(string printerName)
{
System.Printing.PrintQueue printQueue = null;
PrintServer server = new PrintServer(printerName);
foreach (System.Printing.PrintQueue pq in server.GetPrintQueues())
{
if (pq.FullName.Equals(printerName))
{
printQueue = pq;
}
}
return printQueue;
} /// <summary>
/// Get Windows Print Queue via printer name
/// 如果两个printer指向的是同一个物理打印机,则如果copy1的printQueue已经打开,
///则发送到copy2的打印job也会添加到已经打开的copy1的printQueue中.
/// </summary>
/// <param name="printerName"></param>
/// <returns></returns>
public System.Printing.PrintQueue GetOpenedPrintQueueOfSameModel(string printerName)
{
System.Printing.PrintQueue doorOpenedprintQueue = null;
System.Printing.PrintQueue currentPrinterPrintQueue = null;
PrintServer server = new PrintServer(printerName);
foreach (System.Printing.PrintQueue pq in server.GetPrintQueues())
{
if (pq.FullName.Equals(printerName))
{
currentPrinterPrintQueue = pq;
}
else
{
if (IsSameModel(printerName, pq.FullName))
{
if (pq.IsDoorOpened)
{
doorOpenedprintQueue = pq;
break;
}
}
}
} if (doorOpenedprintQueue != null)
{
return doorOpenedprintQueue;
}
else
{
return currentPrinterPrintQueue;
}
}
}
PrinterPropertyManager用于管理打印机的状态以及查询修改打印机属性
class PrinterPropertyManager
2 {
/// <summary>
/// 获取打印机的IP地址和端口号
/// </summary>
/// <param name="printerName">打印机名称</param>
public KeyValuePair<string, int> GetPrinterIPAndPort(string printerName)
{
string port = GetPrinterPropertyValue(printerName, "PortName");
//Query portName's property from regedit
string[] portQuerys = GetPortQuerys(port);
foreach (var portQuery in portQuerys)
{
RegistryKey portKey = Registry.LocalMachine.OpenSubKey(portQuery, RegistryKeyPermissionCheck.Default,
System.Security.AccessControl.RegistryRights.QueryValues);
if (portKey != null)
{
object IPValue = portKey.GetValue("IPAddress", String.Empty,
RegistryValueOptions.DoNotExpandEnvironmentNames);
object portValue = portKey.GetValue("PortNumber", String.Empty,
RegistryValueOptions.DoNotExpandEnvironmentNames);
if (IPValue != null && portValue != null)
{
return new KeyValuePair<string, int>(IPValue.ToString(), (Int32)portValue);
}
}
}
return new KeyValuePair<string, int>();
} /// <summary>
/// determine whether the printer is network printer.
/// </summary>
public bool IsNetWorkPrinter(string printer)
{
string port = GetPrinterPropertyValue(printer, "PortName");
//Query portName's property from regedit
string[] portQuerys = GetNetWorkPortQuerys(port);
foreach (var portQuery in portQuerys)
{
RegistryKey portKey = Registry.LocalMachine.OpenSubKey(portQuery, RegistryKeyPermissionCheck.Default,
System.Security.AccessControl.RegistryRights.QueryValues);
if (portKey != null)
{
return true;
}
}
return false;
} private string[] GetNetWorkPortQuerys(string portName)
{
return new string[]
{
@"System\CurrentControlSet\Control\Print\Monitors\Advanced Port Monitor\Ports\" + portName,
@"System\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\" + portName
};
} private string[] GetPortQuerys(string portName)
{
return new string[]
{
@"System\CurrentControlSet\Control\Print\Monitors\Advanced Port Monitor\Ports\" + portName,
@"System\CurrentControlSet\Control\Print\Monitors\Local Port\Ports\" + portName,
@"System\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\" + portName,
@"System\CurrentControlSet\Control\Print\Monitors\USB Monitor\Ports\" + portName,
@"System\CurrentControlSet\Control\Print\Monitors\WSD Port\Ports\" + portName,
};
} /// <summary>
/// get printer property value
/// </summary>
public string GetPrinterPropertyValue(string printerName, string propertyName)
{ string propertyValue = string.Empty;
//Query printer's portName from WIN32_Printer
string query = string.Format("SELECT * from Win32_Printer WHERE Name = '{0}'", printerName);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection managementObjects = searcher.Get();
foreach (ManagementObject managementObject in managementObjects)
{
PropertyData propertyData = managementObject.Properties[propertyName];
if (propertyData != null)
{
propertyValue = propertyData.Value.ToString();
}
}
return propertyValue;
} /// <summary>
/// change printer property value
/// </summary>
public void SetPrinterPropertyValue(string printerName, string propertyName, string propertyValue)
{ //Query printer's portName from WIN32_Printer
string query = string.Format("SELECT * from Win32_Printer WHERE Name = '{0}'", printerName);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection managementObjects = searcher.Get();
foreach (ManagementObject managementObject in managementObjects)
{
PropertyData propertyData = managementObject.Properties[propertyName];
if (propertyData != null)
{
propertyData.Value = propertyValue;
managementObject.Put();
}
}
}
/// <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;
} /// <summary>
/// 获取打印机名字的列表
/// </summary>
public ArrayList GetPrinterNames()
{
ArrayList result = new ArrayList(); foreach (string ss in PrinterSettings.InstalledPrinters)
{
result.Add(ss);
}
return result;
} /// <summary>
/// 获取打印机状态
/// </summary>
/// <param name="printerName">打印机名称</param>
public PrinterStatus GetPrinterStatus(string printerName,out bool isError,out string errorDescription)
{
//init return variable
isError = false;
errorDescription = string.Empty;
PrinterStatus printerStatus = PrinterStatus.Idle;
if (IsNetWorkPrinter(printerName))
{
KeyValuePair<string, int> ipPortKeyValuePair = GetPrinterIPAndPort(printerName);
PrinterCommunicate printerCommunicate = new PrinterCommunicate();
if (printerCommunicate.CheckNetWorkConnection(ipPortKeyValuePair.Key, ipPortKeyValuePair.Value))
{
WindowsPrintQueue winowsPrintQueue = new WindowsPrintQueue();
if (winowsPrintQueue.IsZebraPrinter(printerName))
{
//get actual status of zebra printer via zebra command
if(IsPause(ipPortKeyValuePair.Key, ipPortKeyValuePair.Value))
{
printerStatus = PrinterStatus.Paused;
} string errorMsg = string.Empty;
if(IsError(ipPortKeyValuePair.Key, ipPortKeyValuePair.Value, out errorMsg))
{
isError = true;
errorDescription = GetZebraPrinterErrorStatusDescription(errorMsg);
}
}
}
else
{
//not connected
printerStatus = PrinterStatus.Offline;
}
}
return printerStatus;
} /// <summary>
/// determine whether the network printer is in pause.Only for zebra model printer
/// </summary>
private bool IsPause(string ip, int port)
{
string strOutMsg = null;
string zebraCommand = "^XA~HS^XZ";
PrinterCommunicate printerCommunicate = new PrinterCommunicate();
if (printerCommunicate.SendZPL_ViaNetwork(ip, port, zebraCommand, out strOutMsg))
{
//split retMsg with "\r\n"
string[] retMsgs = strOutMsg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
if (retMsgs != null)
{
string retFirstMsgItem = retMsgs[];
string[] retFirstMsgItems = retFirstMsgItem.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
return "".Equals(retFirstMsgItems[]);
}
}
return false;
} /// <summary>
/// determine whether the network printer is in error.only for zebra model printer
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <param name="strOutMsg"></param>
/// <returns></returns>
private bool IsError(string ip, int port, out string strOutMsg)
{
strOutMsg = string.Empty;
string zebraCommand = "^XA~HQES^XZ";
PrinterCommunicate printerCommunicate = new PrinterCommunicate();
if (printerCommunicate.SendZPL_ViaNetwork(ip, port, zebraCommand, out strOutMsg))
{
//split retMsg with "\r\n"
string[] retMsgs = strOutMsg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
if (retMsgs != null)
{
for (int i = ; i < retMsgs.Length; i++)
{
string retMsgItem = retMsgs[i];
if (string.IsNullOrEmpty(retMsgItem) || !retMsgItem.Contains(":")) { continue; } string[] retMsgItemSplited = retMsgItem.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
if (retMsgItemSplited == null || retMsgItemSplited.Length == ) { continue; } string errorMsg = retMsgItemSplited[].Trim();
if (!string.IsNullOrEmpty(errorMsg))
{
string errorFlag = errorMsg.Substring(, );
if ("".Equals(errorFlag))
{
strOutMsg = errorMsg;
return true;
}
}
}
}
}
return false;
} /// <summary>
/// get actual status of zebra printer via zebra command.
/// </summary>
/// <param name="ip"></param>
/// <param name="port"></param>
/// <returns></returns>
private string GetZebraPrinterErrorStatusDescription(string errorMsg)
{
StringBuilder status = new StringBuilder();
//error happend
string nibble1 = errorMsg.Substring(errorMsg.Length - , );
string nibble2 = errorMsg.Substring(errorMsg.Length - , );
string nibble3 = errorMsg.Substring(errorMsg.Length - , ); if (!"".Equals(nibble1))
{
Dictionary<int, string> nibble1ErrorDictionary = new Dictionary<int, string>();
nibble1ErrorDictionary.Add(, "Midea Out");
nibble1ErrorDictionary.Add(, "Ribbon Out");
nibble1ErrorDictionary.Add(, "Head Open");
nibble1ErrorDictionary.Add(, "Cutter Fault"); status.Append(GetErrorDescriptionFromNibble(nibble1, nibble1ErrorDictionary));
} if (!"".Equals(nibble2))
{
Dictionary<int, string> nibble2ErrorDictionary = new Dictionary<int, string>();
nibble2ErrorDictionary.Add(, "Printhead Over Temperature");
nibble2ErrorDictionary.Add(, "Motor Over Temperature");
nibble2ErrorDictionary.Add(, "Bad Printhead Element");
nibble2ErrorDictionary.Add(, "Printhead Detection Error"); status.Append(GetErrorDescriptionFromNibble(nibble1, nibble2ErrorDictionary));
} if (!"".Equals(nibble3))
{
Dictionary<int, string> nibble3ErrorDictionary = new Dictionary<int, string>();
nibble3ErrorDictionary.Add(, "Invalid Firmware Config");
nibble3ErrorDictionary.Add(, "Printhead Thermistor Open"); status.Append(GetErrorDescriptionFromNibble(nibble1, nibble3ErrorDictionary));
} string strStatus = status.ToString();
return strStatus.Substring(, strStatus.Length - );
} private StringBuilder GetErrorDescriptionFromNibble(string nibble, Dictionary<int, string> statusDictionary)
{
int intNibble = Convert.ToInt32(nibble);
StringBuilder status = new StringBuilder();
if (statusDictionary != null)
{
foreach (var statusKV in statusDictionary)
{
if ((intNibble & statusKV.Key) == statusKV.Key)
{
status.Append(statusKV.Value);
status.Append(",");
}
}
}
return status;
}
} public enum PrinterStatus
{
Other = ,
Unknown = ,
Idle = ,
Printing = ,
Warmup = ,
Paused = ,
Offline =
}