.NET-код для отправки ZPL на принтеры Zebra
9 ответов
взгляните на эту тему:печать кодов ZPL на принтере ZEBRA с помощью класса PrintDocument.
в частности, OP выбирает эту функцию из ответов на поток:
[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, FileAccess dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes, FileMode dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
private void Print()
{
// Command to be sent to the printer
string command = "^XA^FO10,10,^AO,30,20^FDFDTesting^FS^FO10,30^BY3^BCN,100,Y,N,N^FDTesting^FS^XZ";
// Create a buffer with the command
Byte[] buffer = new byte[command.Length];
buffer = System.Text.Encoding.ASCII.GetBytes(command);
// Use the CreateFile external func to connect to the LPT1 port
SafeFileHandle printer = CreateFile("LPT1:", FileAccess.ReadWrite, 0, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
// Aqui verifico se a impressora é válida
if (printer.IsInvalid == true)
{
return;
}
// Open the filestream to the lpt1 port and send the command
FileStream lpt1 = new FileStream(printer, FileAccess.ReadWrite);
lpt1.Write(buffer, 0, buffer.Length);
// Close the FileStream connection
lpt1.Close();
}
таким образом, Вы сможете отправить ZPL на принтер независимо от того, как он подключен (LPT, USB, Сетевой Ресурс...)
создайте класс RawPrinterHelper (из статьи Microsoft на как отправить необработанные данные на принтер с помощью Visual C# .NET):
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class RawPrinterHelper
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)] public string pDocName;
[MarshalAs(UnmanagedType.LPStr)] public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)] public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint="OpenPrinterA", SetLastError=true, CharSet=CharSet.Ansi, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint="ClosePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint="StartDocPrinterA", SetLastError=true, CharSet=CharSet.Ansi, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool StartDocPrinter( IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint="EndDocPrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint="StartPagePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint="EndPagePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint="WritePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten );
// SendBytesToPrinter()
// When the function is given a printer name and an unmanaged array
// of bytes, the function sends those bytes to the print queue.
// Returns true on success, false on failure.
public static bool SendBytesToPrinter( string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false; // Assume failure unless you specifically succeed.
di.pDocName = "My C#.NET RAW Document";
di.pDataType = "RAW";
// Open the printer.
if( OpenPrinter( szPrinterName.Normalize(), out hPrinter, IntPtr.Zero ) )
{
// Start a document.
if( StartDocPrinter(hPrinter, 1, di) )
{
// Start a page.
if( StartPagePrinter(hPrinter) )
{
// Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if( bSuccess == false )
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
}
public static bool SendFileToPrinter( string szPrinterName, string szFileName )
{
// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open);
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);
// Dim an array of bytes big enough to hold the file's contents.
Byte []bytes = new Byte[fs.Length];
bool bSuccess = false;
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr(0);
int nLength;
nLength = Convert.ToInt32(fs.Length);
// Read the contents of the file into the array.
bytes = br.ReadBytes( nLength );
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
}
public static bool SendStringToPrinter( string szPrinterName, string szString )
{
IntPtr pBytes;
Int32 dwCount;
// How many characters are in the string?
dwCount = szString.Length;
// Assume that the printer is expecting ANSI text, and then convert
// the string to ANSI text.
pBytes = Marshal.StringToCoTaskMemAnsi(szString);
// Send the converted ANSI string to the printer.
SendBytesToPrinter(szPrinterName, pBytes, dwCount);
Marshal.FreeCoTaskMem(pBytes);
return true;
}
}
вызовите метод печати:
private void BtnPrint_Click(object sender, System.EventArgs e)
{
string s = "^XA^LH30,30\n^FO20,10^ADN,90,50^AD^FDHello World^FS\n^XZ";
PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new PrinterSettings();
if(DialogResult.OK == pd.ShowDialog(this))
{
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, s);
}
}
есть 2 gotchas я столкнулся с тем, что происходит, когда вы отправляете txt файлы с ZPL кодами к принтеру:
- файл должен заканчиваться новым символом строки
-
кодировки в кодировку.По умолчанию при чтении файлов ANSI txt со специальными символами
public static bool SendTextFileToPrinter(string szFileName, string printerName) { var sb = new StringBuilder(); using (var sr = new StreamReader(szFileName, Encoding.Default)) { while (!sr.EndOfStream) { sb.AppendLine(sr.ReadLine()); } } return RawPrinterHelper.SendStringToPrinter(printerName, sb.ToString()); }
я управлял проектом, который делает это с сокетами в течение многих лет. Zebra обычно использует порт 6101. Я просмотрю код и опубликую все, что смогу.
public void SendData(string zpl)
{
NetworkStream ns = null;
Socket socket = null;
try
{
if (printerIP == null)
{
/* IP is a string property for the printer's IP address. */
/* 6101 is the common port of all our Zebra printers. */
printerIP = new IPEndPoint(IPAddress.Parse(IP), 6101);
}
socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
socket.Connect(printerIP);
ns = new NetworkStream(socket);
byte[] toSend = Encoding.ASCII.GetBytes(zpl);
ns.Write(toSend, 0, toSend.Length);
}
finally
{
if (ns != null)
ns.Close();
if (socket != null && socket.Connected)
socket.Close();
}
}
самое простое решение-копирование файлов на общий принтер.
Пример на C#:
System.IO.File.Copy(inputFilePath, printerPath);
где:
- inputFilePath-путь к файлу ZPL (специальное расширение не требуется);
- printerPath-путь к общему(!) принтер, например: \127.0.0.1\zebraGX
вот как это сделать с помощью протокола TCP IP:
// Printer IP Address and communication port
string ipAddress = "10.3.14.42";
int port = 9100;
// ZPL Command(s)
string ZPLString =
"^XA" +
"^FO50,50" +
"^A0N50,50" +
"^FDHello, World!^FS" +
"^XZ";
try
{
// Open connection
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
client.Connect(ipAddress, port);
// Write ZPL String to connection
System.IO.StreamWriter writer =
new System.IO.StreamWriter(client.GetStream());
writer.Write(ZPLString);
writer.Flush();
// Close Connection
writer.Close();
client.Close();
}
catch (Exception ex)
{
// Catch Exception
}
источник : ВЕБ-САЙТ ZEBRA
понял, так как это все еще отображается высоко в результатах поиска для C# и ZPL, я должен упомянуть SharpZebra. Это только EPL2, но я представил обновление это добавляет поддержку ZPL вместе с печатью через гнезда, обслуживание Катышкы Windows и сразу USB.
версия VB (с использованием порта 9100 - протестирована на Zebra ZM400)
Sub PrintZPL(ByVal pIP As String, ByVal psZPL As String)
Dim lAddress As Net.IPEndPoint
Dim lSocket As System.Net.Sockets.Socket = Nothing
Dim lNetStream As System.Net.Sockets.NetworkStream = Nothing
Dim lBytes As Byte()
Try
lAddress = New Net.IPEndPoint(Net.IPAddress.Parse(pIP), 9100)
lSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, _ ProtocolType.Tcp)
lSocket.Connect(lAddress)
lNetStream = New NetworkStream(lSocket)
lBytes = System.Text.Encoding.ASCII.GetBytes(psZPL)
lNetStream.Write(lBytes, 0, lBytes.Length)
Catch ex As Exception When Not App.Debugging
Msgbox ex.message & vbnewline & ex.tostring
Finally
If Not lNetStream Is Nothing Then
lNetStream.Close()
End If
If Not lSocket Is Nothing Then
lSocket.Close()
End If
End Try
End Sub
на веб-сайте поддержки Zebra есть ответ:
https://km.zebra.com/kb/index?page=content&id=SA301&cat=ZISV_PL_ZPL&actp=LIST
Я использую комбинацию этих двух
Private Sub sendData(ByVal zpl As String)
Dim ns As System.Net.Sockets.NetworkStream = Nothing
Dim socket As System.Net.Sockets.Socket = Nothing
Dim printerIP As Net.IPEndPoint = Nothing
Dim toSend As Byte()
Try
If printerIP Is Nothing Then
'set the IP address
printerIP = New Net.IPEndPoint(IPAddress.Parse(IP_ADDRESS), 9100)
End If
'Create a TCP socket
socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
'Connect to the printer based on the IP address
socket.Connect(printerIP)
'create a new network stream based on the socket connection
ns = New NetworkStream(socket)
'convert the zpl command to a byte array
toSend = System.Text.Encoding.ASCII.GetBytes(zpl)
'send the zpl byte array over the networkstream to the connected printer
ns.Write(toSend, 0, toSend.Length)
Catch ex As Exception
MessageBox.Show(ex.Message, "Cable Printer", MessageBoxButtons.OKCancel, MessageBoxIcon.Error)
Finally
'close the networkstream and then the socket
If Not ns Is Nothing Then
ns.Close()
End If
If Not socket Is Nothing Then
socket.Close()
End If
End Try
End Sub
Private Function createString() As String
Dim command As String
command = "^XA"
command += "^LH20,25"
If rdoSmall.Checked = True Then
command += "^FO1,30^A0,N,25,25^FD"
ElseIf rdoNormal.Checked = True Then
command += "^FO1,30^A0,N,35,35^FD"
Else
command += "^FO1,30^A0,N,50,50^FD"
End If
command += txtInput.Text
command += "^FS"
command += "^XZ"
Return command
End Function