原本是使用网络上最流行的环路网卡方式套印标签,但是最近公司电脑换win7的,麻烦就来了。这个麻烦纠结了我两周,中间还把标签机搬到办公室来测试,累死了都(估计卖废铁能买个好价钱)。
采用环路网卡调用时,驱动kernel32.dll时,无法连接到标签机,但是打印测试又是ok的。个人分析情况两种:一种就是我的zebra打印驱动方式不对(虽然后面网上下了专门win7的,但是依然不行);一种就是Windows 9x/Me中非常重要的32位动态链接库文件,属于内核级文件,系统很可能里面的API接口变了。
基本上确认原有方法无解后,就换了个方式,即期待预把标签机当作一般打印机使用,所以我就使用了水晶报表,照着原有格式慢慢调试,最后打印效果差强人意,还有就是打印一段时间标签机参数都会还原回去。最后在网上找到一种使用winspool.Drv驱动标Zebra标签机的方法,能够使用ZPII编程语言驱动标签机,才算是圆满解决问题了。
驱动类 RawPrinterHelper
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.IO; 5 using System.Drawing; 6 using System.Drawing.Printing; 7 using System.Windows.Forms; 8 using System.Runtime.InteropServices; 9 10 namespace ZPLPrinter 11 { 12 class RawPrinterHelper 13 { 14 // 结构和API声明 15 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 16 public class DOCINFOA 17 { 18 [MarshalAs(UnmanagedType.LPStr)] 19 public string pDocName; 20 [MarshalAs(UnmanagedType.LPStr)] 21 public string pOutputFile; 22 [MarshalAs(UnmanagedType.LPStr)] 23 public string pDataType; 24 } 25 [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 26 public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); 27 28 [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 29 public static extern bool ClosePrinter(IntPtr hPrinter); 30 31 [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 32 public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); 33 34 [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 35 public static extern bool EndDocPrinter(IntPtr hPrinter); 36 37 [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 38 public static extern bool StartPagePrinter(IntPtr hPrinter); 39 40 [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 41 public static extern bool EndPagePrinter(IntPtr hPrinter); 42 43 [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 44 public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); 45 46 /// <summary> 47 /// 发送byte值给打印机 48 /// </summary> 49 /// <param name="szPrinterName">打印机名称</param> 50 /// <param name="pBytes">byte</param> 51 /// <param name="dwCount">字符长度</param> 52 /// <returns>成功标记(true为成功)</returns> 53 public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount) 54 { 55 Int32 dwError = 0, dwWritten = 0; 56 IntPtr hPrinter = new IntPtr(0); 57 DOCINFOA di = new DOCINFOA(); 58 bool bSuccess = false; // 返回标志,默认失败 59 di.pDocName = "My Zebra Print File"; 60 di.pDataType = "RAW"; 61 62 // 打开打印机 63 if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) 64 { 65 // 开始文档 66 if (StartDocPrinter(hPrinter, 1, di)) 67 { 68 // 开始页 69 if (StartPagePrinter(hPrinter)) 70 { 71 // 写比特流 72 bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); 73 EndPagePrinter(hPrinter); 74 } 75 EndDocPrinter(hPrinter); 76 } 77 ClosePrinter(hPrinter); 78 } 79 // 如果不成功,写错误原因 80 if (bSuccess == false) 81 { 82 dwError = Marshal.GetLastWin32Error(); 83 } 84 return bSuccess; 85 } 86 87 /// <summary> 88 /// 将字符串转换为bytes值,驱动bytes打印函数 89 /// </summary> 90 /// <param name="szPrinterName"></param> 91 /// <param name="szString"></param> 92 /// <returns></returns> 93 public static bool SendStringToPrinter(string szPrinterName, string szString) 94 { 95 //for (int i = 0; i < 3; i++) 96 //{ 97 IntPtr pBytes; 98 Int32 dwCount; 99 //字符串长度 100 dwCount = szString.Length; 101 // 转换ANSIbyte码 102 pBytes = Marshal.StringToCoTaskMemAnsi(szString); 103 //驱动byte打印 104 SendBytesToPrinter(szPrinterName, pBytes, dwCount); 105 Marshal.FreeCoTaskMem(pBytes); 106 107 //} 108 return true; 109 } 110 } 111 }
主函数(这是一个画面摘下来的,大家看 btnPrintZPL_Click调用了驱动函数)
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Text; 7 using System.Windows.Forms; 8 using System.Runtime.InteropServices; 9 10 namespace ZPLPrinter 11 { 12 public partial class Form1 : Form 13 { 14 15 private void btnPrintZPL_Click(object sender, EventArgs e) 16 { 17 //将标签机名和ZPII字符串发送给标签机 18 RawPrinterHelper.SendStringToPrinter("Zebra ZM400 300 dpi (ZPL)", SM0001()); 19 20 } 21 22 23 //标签打印 24 private string SM0001() 25 { 26 27 //string prod_code = "HA"; //品名代码 28 string prod_cname = "鋼卷"; //品名 29 string prod_cname_long = ""; //2014-01-03 品名 30 string v_prod_ename = "Hot Rolled Stainless Steel Sheet in Coil"; //品名英文 31 string v_sg_std = "JIS G4304"; //标准 32 string v_mat_no = "HE1300084200"; //材料号 33 string v_sg_sign = "SUS304"; //牌号 34 string v_size = "2.97mm x 1240mm x Coil"; //尺寸 35 string v_gross_wt = "20.110"; //毛重 36 string v_net_wt = "20.040"; //净重 37 string v_grade = "1"; //等级 38 string v_grade_cn = "1"; //等级 39 //string v_surface = "No.1"; //表面 40 string c_surface = "No.1"; //表面描述 41 string v_edge = "M"; //边部 42 string v_order_no = ""; //合同号 43 string v_heat_no = "1000076"; //炉号 44 string v_date = "2014.01.27"; //日期 45 string data = ""; //打印数据 46 string cn_prod_cname = ""; 47 string cn_prod_cname_long = ""; 48 string cn_grade = ""; 49 string v_mat_act_thick = "(3.00mm)"; 50 51 //prod_cname_long = 鋼卷"; 52 //string c_div = "M"; //碳锈区分 53 //string cn_surface = ""; 54 int j = 0; 55 56 //等级中文代码 //简体中文转换繁体中文 57 System.Text.Encoding gb2312 = System.Text.Encoding.GetEncoding("gb2312"); 58 System.Text.Encoding big5 = System.Text.Encoding.GetEncoding("big5"); 59 v_grade_cn = "級"; 60 byte[] bGB2312 = gb2312.GetBytes(v_grade_cn); 61 byte[] bBig5 = System.Text.Encoding.Convert(gb2312, big5, bGB2312); 62 string result = big5.GetString(bBig5); 63 //品名 64 LPTControl getChinese = new LPTControl(); 65 cn_prod_cname = getChinese.PrintChinese(prod_cname, "標楷體", 100, 40, 1, 0); 66 67 //品名超长 68 LPTControl getChinese02 = new LPTControl(); 69 cn_prod_cname_long = getChinese.PrintChinese(prod_cname_long, "標楷體", 100, 40, 1, 0); 70 71 //等级 72 LPTControl getChinese01 = new LPTControl(); 73 cn_grade = getChinese01.PrintChinese(result, "標楷體", 100, 40, 1, 0); 74 ////表面 75 //LPTControl getChinese02 = new LPTControl(); 76 //cn_surface = getChinese02.PrintChinese(v_surface, "黑体", 45, 25, 1, 0); 77 #region//最初 78 System.Text.StringBuilder sw = new System.Text.StringBuilder("^XA\r\n", 10240); 79 sw.Append(@"^LH0,0" + "\r\n"); 80 sw.Append(@"^POI" + "\r\n"); //反向 81 //默认生成的图片都是OUTSTR01,品名中文 82 sw.Append(cn_prod_cname.Replace("OUTSTR01", "OUTSTR" + j.ToString()) + "\r\n"); 83 sw.Append(@"^FO780,460"); 84 sw.Append(@"^XGOUTSTR" + j.ToString() + ",1,1^FS" + "\r\n"); 85 //品名超长 modified by zxq on 2014-01-04 86 if (prod_cname_long.Length > 0) 87 { 88 sw.Append(cn_prod_cname_long.Replace("OUTSTR01", "OUTSTRB" + j.ToString()) + "\r\n"); 89 sw.Append(@"^FO780,1112"); 90 sw.Append(@"^XGOUTSTRB" + j.ToString() + ",1,1^FS" + "\r\n"); 91 } 92 //品名英文 93 sw.Append(@"^FO720,460"); 94 sw.Append((@"^A0R,60,50^FD" + v_prod_ename + "^FS" + "\r\n"));//60,50打印较饱满 95 sw.Append(@"^FO560,460^A0R,140,140^FD" + v_mat_no + "^FS" + "\r\n"); 96 sw.Append(@"^FO450,460^A0R,90,90^FD" + v_sg_std + "^FS" + "\r\n"); 97 sw.Append(@"^FO320,460^A0R,90,90^FD" + v_sg_sign + "^FS" + "\r\n"); 98 sw.Append(@"^FO250,460^A0R,80,80^FD" + v_size + "^FS" + "\r\n"); 99 sw.Append(@"^FO190,460^A0R,80,80^FD" + v_mat_act_thick + "^FS" + "\r\n"); 100 sw.Append(@"^FO60,460^A0R,90,90^FD" + v_gross_wt + "^FS" + "\r\n"); 101 sw.Append(@"^FO60,1130^A0R,90,90^FD" + v_net_wt + "^FS" + "\r\n"); 102 //等级 103 sw.Append(@"^FO700,1800^A0R,180,180^FD" + v_grade + "^FS" + "\r\n"); 104 //等级中文(级汉字) 105 sw.Append(@"^FO730,1900"); 106 sw.Append(cn_grade.Replace("OUTSTR01", "OUTSTRA" + j.ToString()) + "\r\n"); 107 sw.Append(@"^XGOUTSTRA" + j.ToString() + ",1,1^FS" + "\r\n"); 108 //表面 109 sw.Append(@"^FO600,1800"); 110 sw.Append(@"^A0R,90,90^FD" + c_surface + "^FS" + "\r\n"); 111 //sw.Append(cn_surface.Replace("OUTSTR01", "OUTSTRB" + j.ToString()) + "\r\n"); 112 //sw.Append(@"^XGOUTSTRB" + j.ToString() + ",2,2^FS" + "\r\n"); 113 sw.Append(@"^FO450,1800^A0R,90,90^FD" + v_edge + "^FS" + "\r\n"); 114 sw.Append(@"^FO320,1800^A0R,90,90^FD" + v_order_no + "^FS" + "\r\n"); 115 sw.Append(@"^FO190,1800^A0R,90,90^FD" + v_heat_no + "^FS" + "\r\n"); 116 sw.Append(@"^FO60,1800^A0R,90,90^FD" + v_date + "^FS" + "\r\n"); 117 //条形码 118 sw.Append(@"^FO180,2290^BY4,3,130^B3N,N,,N,N^FD" + v_mat_no + "^FS" + "\r\n"); 119 sw.Append(@"^XZ"); 120 #endregion 121 122 123 data = sw.ToString(); 124 MessageBox.Show("返回数据"); 125 126 data = sw.ToString(); 127 128 return data; 129 } 130 131 //使用LPT1连接打印机,进行打印 2013-8-8 by zxq 132 public class LPTControl 133 { 134 [StructLayout(LayoutKind.Sequential)] 135 private struct OVERLAPPED 136 { 137 int Internal; 138 int InternalHigh; 139 int Offset; 140 int OffSetHigh; 141 int hEvent; 142 } 143 144 [DllImport("kernel32.dll")] 145 private static extern int CreateFile( 146 string lpFileName, 147 uint dwDesiredAccess, 148 int dwShareMode, 149 int lpSecurityAttributes, 150 int dwCreationDisposition, 151 int dwFlagsAndAttributes, 152 int hTemplateFile 153 ); 154 155 [DllImport("kernel32.dll")] 156 private static extern bool WriteFile( 157 int hFile, 158 byte[] lpBuffer, 159 int nNumberOfBytesToWrite, 160 out int lpNumberOfBytesWritten, 161 out OVERLAPPED lpOverlapped 162 ); 163 164 165 [DllImport("kernel32.dll")] 166 private static extern bool CloseHandle( 167 int hObject 168 ); 169 170 [DllImport("FNTHEX32.DLL")] 171 public static extern int GETFONTHEX( 172 string ChineseText, //待转变中文内容 173 string FontName, //字体名称 174 int Orient, //旋转角度0,90,180,270 175 int Height, // 字体高度 176 int Width, // 字体宽度,通常是0 177 byte IsBold, //1 变粗,0 正常 178 byte IsItalic, //1 斜体,0 正常 179 System.Text.StringBuilder ReturnPicData); //返回的图片字符 180 181 private int iHandle; 182 private string cName; //中文名 183 public bool Open() 184 { 185 iHandle = CreateFile("lpt1", 0x40000000, 0, 0, 3, 0, 0); 186 if (iHandle != -1) 187 { 188 return true; 189 } 190 else 191 { 192 return false; 193 } 194 } 195 196 public bool Write(String Mystring) 197 { 198 if (iHandle != -1) 199 { 200 int i; 201 OVERLAPPED x; 202 byte[] mybyte = System.Text.Encoding.Default.GetBytes(Mystring); 203 return WriteFile(iHandle, mybyte, mybyte.Length, out i, out x); 204 } 205 else 206 { 207 throw new Exception("埠未打開!"); 208 } 209 } 210 211 public bool Close() 212 { 213 return CloseHandle(iHandle); 214 } 215 216 public string PrintChinese(string sChn, string sFont, int nHeight, int nWidth, byte nBold, byte nItalic) 217 { 218 StringBuilder hexbuf = new StringBuilder(21 * 1024); 219 int count = GETFONTHEX(sChn, sFont, 90, nHeight, nWidth, nBold, nItalic, hexbuf); 220 221 cName = hexbuf.ToString(); 222 return (cName); 223 } 224 } 225 226 227 } 228 229 230 }
我测试了一下在32位系统上使用完全能够胜任,64位还是有问题。。。。