我是初学C#程序员。我有一个项目要求我通过USB将原始命令发送到Zebra打印机LP 2844并使其工作。我做了很多研究,并试图找到一种方法来做到这一点。我使用http://support.microsoft.com/kb/322091中的代码,但它没有用。根据我的测试,似乎我已经向打印机发送了命令,但它没有响应和打印。我不知道这个。有人可以帮助我吗?
我使用按钮直接发送命令
private void button2_Click(object sender, EventArgs e)
{
string s = "A50,50,0,2,1,1,N,\"9129302\"";
// Allow the user to select a printer.
PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new PrinterSettings();
if (DialogResult.OK == pd.ShowDialog(this))
{
// Send a printer-specific to the printer.
RawPrinterHelper.SendStringToPrinter(pd.PrinterSettings.PrinterName, s);
MessageBox.Show("Data sent to printer.");
}
}
答案 0 :(得分:13)
编辑:要解决您的更新问题,您遇到的问题是您正在使用SendStringToPrinter
向打印机发送ANSI字符串(空终止)字符串,而不是打印机期待。官方EPL2 programming guide第23页(根据你的例子,这是你真正做的,而不是ZPL)。
每个命令行必须以换行(LF)字符终止 (12月10日)。大多数基于PC的系统在Enter键为时发送CR / LF 按下。打印机忽略回车符(CR)字符 并且不能用来代替LF。
因此,您必须修改SendStringToPrinter
以在字符串末尾发送\n
而不是\0
,或者您必须自己构建ASCII字节数组并使用RawPrinterHelper.SendBytesToPrinter
你自己(就像我在下面的原始答案中所做的那样)。
因此,为了修复您的简单发布示例,我们更改了您的函数调用,我们还必须通过发送P1\n
private void button2_Click(object sender, EventArgs e)
{
string s = "A50,50,0,2,1,1,N,\"9129302\"\n";
s += "P1\n";
// Allow the user to select a printer.
PrintDialog pd = new PrintDialog();
pd.PrinterSettings = new PrinterSettings();
if (DialogResult.OK == pd.ShowDialog(this))
{
var bytes = Encoding.ASCII.GetBytes(s);
// Send a printer-specific to the printer.
RawPrinterHelper.SendBytesToPrinter(pd.PrinterSettings.PrinterName, bytes, bytes.Length);
MessageBox.Show("Data sent to printer.");
}
}
//elsewhere
public static class RawPrinterHelper
{
//(Snip) The rest of the code you already have from http://support.microsoft.com/kb/322091
[DllImport("winspool.Drv", EntryPoint="WritePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, byte[] pBytes, Int32 dwCount, out Int32 dwWritten );
private static bool SendBytesToPrinter(string szPrinterName, byte[] bytes, Int32 dwCount)
{
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false;
di.pDocName = "Zebra Label";
di.pDataType = "RAW";
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
{
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
bSuccess = WritePrinter(hPrinter, bytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
throw new Win32Exception(dwError);
}
return bSuccess;
}
}
我用Zebra的旧版EPL2语言做到了这一点,但它应该与你需要用ZPL做的非常相似。也许它会让你开始朝着正确的方向前进。
public class Label
{
#region Print logic. Taken from http://support.microsoft.com/kb/322091
//Snip stuff unchanged from the KB example.
[DllImport("winspool.Drv", EntryPoint="WritePrinter", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, byte[] pBytes, Int32 dwCount, out Int32 dwWritten );
private static bool SendBytesToPrinter(string szPrinterName, byte[] Bytes, Int32 dwCount)
{
Int32 dwError = 0, dwWritten = 0;
IntPtr hPrinter = new IntPtr(0);
DOCINFOA di = new DOCINFOA();
bool bSuccess = false;
di.pDocName = "Zebra Label";
di.pDataType = "RAW";
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
{
if (StartDocPrinter(hPrinter, 1, di))
{
if (StartPagePrinter(hPrinter))
{
bSuccess = WritePrinter(hPrinter, Bytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
throw new Win32Exception(dwError);
}
return bSuccess;
}
#endregion
public byte[] CreateCompleteCommand(bool headerAndFooter)
{
List<byte> byteCollection = new List<byte>();
//Static header content describing the label.
if (headerAndFooter)
{
byteCollection.AddRange(Encoding.ASCII.GetBytes("\nN\n"));
byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("S{0}\n", this.Speed)));
byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("D{0}\n", this.Density)));
byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("q{0}\n", this.LabelHeight)));
if (this.AdvancedLabelSizing)
{
byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("Q{0},{1}\n", this.LableLength, this.GapLength)));
}
}
//The content of the label.
foreach (var command in this.Commands)
{
byteCollection.AddRange(command.GenerateByteCommand());
}
//The footer content of the label.
if(headerAndFooter)
byteCollection.AddRange(Encoding.ASCII.GetBytes(String.Format("P{0}\n", this.Pages)));
return byteCollection.ToArray();
}
public bool PrintLabel(string printer)
{
byte[] command = this.CreateCompleteCommand(true);
return SendBytesToPrinter(printer, command, command.Length);
}
public List<Epl2CommandBase> Commands { get; private set; }
//Snip rest of the code.
}
public abstract partial class Epl2CommandBase
{
protected Epl2CommandBase() { }
public virtual byte[] GenerateByteCommand()
{
return Encoding.ASCII.GetBytes(CommandString + '\n');
}
public abstract string CommandString { get; set; }
}
public class Text : Epl2CommandBase
{
public override string CommandString
{
get
{
string printText = TextValue;
if (Font == Fonts.Pts24)
printText = TextValue.ToUpperInvariant();
printText = printText.Replace("\\", "\\\\"); // Replace \ with \\
printText = printText.Replace("\"", "\\\""); // replace " with \"
return String.Format("A{0},{1},{2},{3},{4},{5},{6},\"{7}\"", X, Y, (byte)TextRotation, (byte)Font, HorziontalMultiplier, VertricalMultiplier, Reverse, printText);
}
set
{
GenerateCommandFromText(value);
}
}
private void GenerateCommandFromText(string command)
{
if (!command.StartsWith(GetFactoryKey()))
throw new ArgumentException("Command must begin with " + GetFactoryKey());
string[] commands = command.Substring(1).Split(',');
this.X = int.Parse(commands[0]);
this.Y = int.Parse(commands[1]);
this.TextRotation = (Rotation)byte.Parse(commands[2]);
this.Font = (Fonts)byte.Parse(commands[3]);
this.HorziontalMultiplier = int.Parse(commands[4]);
this.VertricalMultiplier = int.Parse(commands[5]);
this.ReverseImageColor = commands[6].Trim().ToUpper() == "R";
string message = String.Join(",", commands, 7, commands.Length - 7);
this.TextValue = message.Substring(1, message.Length - 2); // Remove the " at the beginning and end of the string.
}
//Snip
}
答案 1 :(得分:1)
如果人们试图从上面的答案中获得该片段:
[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);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, byte[] pBytes, Int32 dwCount, out Int32 dwWritten);