我正在开发一个项目,我们需要使用Zebra打印机来处理条形码标签 . 我们正在使用C#,我们在打印方面做得很好,将原始ZPL字符串发送到打印机(使用winspool.drv) .
但是,我们还需要从打印机读取,并没有运气 .
我们需要从打印机获取状态,这是ZPL命令“~HS”的输出,因此我们可以判断内存中有多少标签等待打印 . winspool.drv中的EnumJobs()只在Windows假脱机上有作业,一旦它们被发送到打印机,它们就会从该列表中消失 . 但这并不意味着标签已被打印,因为打印机有一个剥离传感器,一次只打印一个标签,我们显然对将批量标签发送到打印机感兴趣 .
我尝试了类似的东西(使用winspool.drv调用):
OpenPrinter(szPrinterName, out hPrinter, IntPtr.Zero);
WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); // send the string "~HS"
ReadPrinter(hPrinter, data, buff, out pcRead);
但我在ReadPrinter调用中什么也得不到 . 我甚至不知道这是否是正确的方法 .
之前有人解决了这个问题吗?
谢谢 .
5 回答
我面临着同样的问题 . 你有没有关于这个主题的任何事情?
Axe Perez Parra Castro,我就是这样做的:
-my printer(zebra 2030)不支持ZPL,所以据我所知,唯一的方法就是向它发送unicode
(从en.wikipedia.org/wiki/ASCII获取那些int值)
组成命令 - 例如
sb.Append(esc + enq + Convert.ToChar(7).ToString());
(从打印机手册中,命令<ESC> <ENQ> <7>应该获得固件版本)发送命令
RawPrinterHelper.SendStringToPrinter(printerName, sb.ToString());
(在我的情况下,printerName是"Zebra TTP 2030")ReadPrinter
在这种情况下无济于事 . 它将回读您提交给打印机的打印作业,而不是打印机的响应 . 但是,为了完整起见:要使用ReadPrinter
,必须使用组合的"printer name - job id"语法再次打开打印机:这仅在作业12345尚未移除时才有效 .
至于回答问题,你必须使用
WriteFile
发送数据和ReadFile
来获得响应 . 要使用这些功能,您需要使用CreateFile
打开打印机 . 完成后,其余的都是微不足道的 .这里的问题是获取必须传递给
CreateFile
的设备路径才能打开打印机 . 如果您的打印机是LPT打印机,那就像"LPT:"
一样简单,但对于USB打印机,您必须获取设备路径,如下所示:我找到了way to obtain this path,但只有安装了一台打印机才能使用 . 如果你有更多,你需要设备路径和你在控制面板中看到的打印机名称之间的关系,这种关系是我为此创建了一个问题:Figuring which printer name corresponds to which device ID .
大约15年前,我编写了通过Zebra打印机打印的软件 .
当我们通过RS-232(?标准串行通信)与打印机通信时,这种方式运行良好,所有信息都以及时准确的方式从打印机返回 .
最近我会使用Epson理货打印机,发现Windows打印机驱动程序笨拙且效率低下 . 我通过GDI直接与打印机通信,一切都令我满意 .
我说取出中间人,如果你下降一个级别并直接与打印机通信,而不是通过Windows打印机驱动程序进行通信,你将获得更多的成功 .
希望这可以帮助,
如果你有机会使用
kernel32.dll
并省略usb-driver-boundwinspool.srv
,你可以使用这种香草方法:Otherwise there's a solution available (it's VB.NET though)(但我不知道这是否适用于ZPL / EPL /指纹/ ......打印机),它使用GetPrinter和
PRINTER_INFO_2
.还有pinvoke.net available的翻译 .
我使用了与C的TCP / IP通信,我能够从打印引擎响应 .