如果是通过ESC/POS指令控制而非调用驱动的话, 可以使用十六进制指令 10 04 02来查询打印机状态是否缺纸
打印的一段内容很长,打印到一半就没纸了,如果这时有返回参来确定打印内容不完全就好了?
检查打印机状态也不能完美解决这个问题!!
@gary_deng: 首先要看你使用的是什么打印接口, 我做的是ESC\POS控制, 而ESC指令里本身没有判断打印是否正常完成的功能, 除非某些厂家单独增加的指令
我的做法是, 打印前检测打印机状态是否正常, 正常则开始打印, 打印时不断的在检测打印机状态(因为那个10 04指令是实时返回的), 如果出现不正常状态(比如缺纸/打印头过热, 或者突然断电造成的长时间没反应)就认为本次打印没有正常完成, 直到下一次打印机正常以后再次重发这个打印作业
或者你也可以使用主动状态返回(ASB)来获取打印机状态 开启指令是十六进制 1D 61 FF, 这个东西只要是打印机状态有更新时就会自动返回给你状态
具体指令你要找打印机供应商看他都支持什么指令以及其参数和返回值
公用的指令都是爱普生的ESC\POS指令: http://wenku.baidu.com/view/b5cb1b16a2161479171128fc
如果你是走驱动的话我就不清楚了, 不过我想Printing里面应该有获得打印完成状态的东西吧, 毕竟这东西和windows打印任务管理器是一体的
@堕落恶魔: 你说的这个办法,我也做过!但是还是不能完美的解决。如果能知道发送过的消息内容打印完,
就能很好的解决一这个问题了!!
@堕落恶魔:
你说的这个办法,我也做过!但是还是不能完美的解决。如果能知道发送过的消息内容打印完,
就能很好的解决一这个问题了!!
还有个问题就是,如果一个list集合有多个字符串。
循环发送这些消息,每发送一个字符串对象,就建立起一个链接,发送完这个字符串对象就关闭。
但是由于发送的速度比打印的速度要快的时候,往往发送了多条消息,只打印了最后一条消息,也就是说前面发送的消息都被覆盖了!!早成这个现象的原因能解决吗?
@gary_deng: 我现在做的就是ESC打印控制程序, 运行了2年多没遇到什么不完美的问题, 除了网口打印机因为网络状态不好可能造成重复打印以外
我做的软件和打印机建立的是长连接, 无论串口还是网口, 一开始也想过发送一次就建立一次连接, 但是后来发现连接速度很慢, 而且频繁连接状态不是很稳定, 还有就是如果不用的时候断开连接, 很可能造成端口被别的程序占用
不过我还没见过发送很多条的时候后面会吧前面覆盖的, 主要还是看你发送的信息量有多大, 这个要看你打印机的缓存, 如果发送的内容超过缓存大小那才会造成信息覆盖, 我的做法是 每次只发送缓存3/4大小的数据,根据普通打印速度等待一个大概的时间再发送其他数据
@堕落恶魔:我没有使用过长连接。有次测试的时候,就出现了这个覆盖的问题,我发送的内容很少,就是循环连接发送,发送速度快。?局域网内,用发送一次连接一次的方式,应该不会很慢吧!!
@gary_deng: 这个我就不太清楚了, 覆盖也许是打印机本身的问题, 至少我目前没遇到过, 你用的是页模式还是行模式, 如果是行模式应该不会覆盖了, 页模式我没测试过, 不过理论上也不会
每次建立socket连接都相对耗时间啊....
@堕落恶魔: 是的,所以现在也想做成长连接了!!但是其中一方不在局域网中(掉线了),你是怎么处理的?
@gary_deng: Socket连接可以得到断线消息啊. 一旦连接断开那就过一段时间尝试重新建立连接呗
@堕落恶魔: 我这边做了个测试,如果是客户端(程序)这边掉线的话,是会报出sokcet异常的;但是直接把打印机的网线给把了,然后调试运行,socket发送消息没报异常,和正常发送没有区别!。。打印机端掉线,你是如何处理的?
@gary_deng: 打印机直接拔网线会产生Socket超时, 不过这个超时时间挺长的, 好像默认是30秒
我的做法是定时发送检测打印机状态指令, 并监听这个指令的返回值, 如果超过一定时间(我的设定是0.8秒)仍然没有收到当前指令的返回值, 那么说明打印机连接异常, 然后重新发送一次指令, 如果仍然超时,那就认为连接异常断开了, 然后程序主动断开Socket连接并且尝试重连
@堕落恶魔:默认的三十秒是否可以修改成1秒或者其他更小的值呢? 发送检测打印机状态指令?还会有返回值?可以根据这个返回值判断打印机是否在打印状态?
@gary_deng: 应该可以改
指令会有返回值, 你找ESC/POS指令说明去看看就知道了, 指令上面我已经告诉你了
不能检测打印机是否在打印, 只能检测一些状态, 具体还是去看ESC/POS指令说明
@堕落恶魔: 指令我都看了,但是socket.send过去的时候,并未有返回值。。
@gary_deng: 那你就要找打印机厂商让他们提供打印机的技术支持资料了 看看是不是打印机本身不支持这个指令
我接触的80MM打印机都支持 58MM大部分都不支持
@堕落恶魔: 现在开发的机子是POS 90,你接受打印机返回值,是使用socket.Receive来接受的吗?
@gary_deng: 对
@堕落恶魔: 那就必须要改一个线程去跑这个接受的方法。
@堕落恶魔: 我现在是做成一个线程去跑这个接收方法。如果命令发过去的话,是会有返回值的。
@gary_deng: -_-......原来你一直单进程在跑啊......我是每个打印机一个线程
@堕落恶魔: 发送指令在另外一个线程当中,而接收返回值的信息是在另外一条独立的线程当中。那么这时又遇到个问题了,就是发送指令过去,怎么才能及时收到他的返回值?然后在发送指令这条线程得到这个返回值在进行判断!
@堕落恶魔: 是可以做成发送打印指令,然后调用socket.Receive获取返回值;在vs 2010 .net4.0下是运行真长的,代码移植到vs 2008 .net3.5 的环境下,靠!send.SendTimeout and send.ReceviveTimeout 这两个属性居然不支持!!!
@gary_deng: -_-....我是吧所有有返回值的指令都按顺序发送 收到一个的返回值才发送另一个, 这里设计就比较复杂了, 包括返回值判断校验什么的
@堕落恶魔: 做了那么多,发现在wince下不支持send.SendTimeout and send.ReceviveTimeout这两个属性的运行,现在要另想办法发送完了之后,去查看socket是否有返回值
@gary_deng: WINCE......没做过
@堕落恶魔: 只能用Socket.select 或者socket.Poll来检查socket是否有读取状态。。
但是只有打印机打印完了,还会有返回值,所以这个时间要配合好
通过WMI获取打印机状态,参考:How to get Printer Info in .NET?
是pos 90打印机,不是多功能打印机。
而且还是网络链接的
@gary_deng: 试试System.Printing.PrintServer,参考:How to: Remotely Survey the Status of Printers
@dudu: 网口连接是通过sokcet建立连接,然后发送ESC/POS打印内容,不是驱动打印!
@gary_deng: 参考:C# Socket Print sometimes no response?