原本是使用網絡上最流行的環路網卡方式套印標簽,但是最近公司電腦換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位還是有問題。。。。