我们在网络上有一些 Windows 机顶盒,并且在它们上面共享打印机。
我已经通过 CUPS 网络界面添加了它们,它们都运行良好,我们可以通过 php 打印到它们:
exec('lp -d vasosamsung file.pdf');
太棒了。我写了一个Printer
类,在打印作业开始之前进行一些验证。
我首先检查的是打印机是否存在:
lpstat -p vasosamsung
如果没有,则表示目的地无效,是的,继续前进。接下来是棘手的部分。
如果答案是空闲,或者正在打印,则一切正常,让我们发送作业。
但!
问题是它说打印机处于空闲状态,因为在我的机器上打印机已添加到打印机列表中,但遗憾的是它处于脱机状态。这就是我想要捕捉的。更多问题来了。
好的,我可以处理它,即使打印机本身处于离线状态(从机器中拉出),作业也在队列中。
真正的问题是,当我通过右键单击并删除设备从“打印机和设备”中删除整个打印机时,CUPS 说它处于空闲状态。我已通过 重新启动 CUPS service cups restart
,并获取以下统计数据:
printer vasosamsung is idle. enabled since Thu 06 Apr 2017 03:34:26 PM CEST
事实并非如此。现在我的机器上已经有这样的打印机了。最糟糕的是,如果我向它发送文档,它会说:
string(40) "request id is vasosamsung-71 (1 file(s))"
并且该作业在 Web 界面上:
vasosamsung-71 Unknown Withheld 1933k 1 held since
2017 年 4 月 6 日 星期四 15:59:43
我的问题是:有没有办法获取物理打印机状态?离线、打印等...不是通过 CUPS?
如果不可能,我能以某种方式了解打印机是否至少在目标机器的设备列表中吗?
编辑
呵呵,当我关掉机器时,打印机也处于空闲状态:)
我猜,这是因为 vasosamsung 打印机位于 CUPS 中,而这不是 phiscal 设备,现在我明白了,但我的问题仍然存在。
答案1
lpstat
与参数一起使用-t
:
$ lpstat -t
scheduler is running
system default destination: DCP-7065DN
device for DCP-7065DN: usb://Brother/DCP-7065DN?serial=<REDACTED>
DCP-7065DN accepting requests since Tue 19 Nov 2019 04:29:56 PM MST
printer DCP-7065DN is idle. enabled since Tue 19 Nov 2019 04:29:56 PM MST
系统告诉我们打印机正在接受请求,例如“一切就绪”。
答案2
我的解决方案:在用 CI 编写的程序中包含该函数(或用我的第一语言 ALGOL 编写的程序,1964 年...)
#define BUFFERLEN 1024
int isprtready( void )
{ char cmd[BUFFERLEN], buffer[BUFFERLEN], usbstat[]="lsusb > ",
enabled[]="Hewlett-Packard LaserJet 2420", filename[]="prtreadyXXXXXX";
int handle, len;
handle = mkstemp( filename );
strcpy( cmd, usbstat );
strcat( cmd, filename );
system( cmd );
len = read( handle, buffer, BUFFERLEN );
buffer[len] = '\0';
close( handle );
unlink( filename );
return ( strstr( buffer, enabled ) != (char*)NULL );
}
具有必需包含的
缺点:我的程序中有明确的打印机名称。(我只有一台计算机和一台打印机,没有网络等。)
答案3
因此真正的问题是如何让 cups 告诉您打印机不存在。
将打印机设置为拒绝所有,它就不会显示为打印机。打印机恢复后,拒绝所有。
lpadmin -p 打印机名称 -u 拒绝:全部
lpadmin -p 打印机名称 -u 拒绝:无
这是我必须在本地做的事情,所以我的应用程序不会显示离线打印机。
在这种情况下,您正在运行服务器,因此将 -o Printer-is-shared=true 更改为 false 也可以。