我尝试了在Java中使用PrintServiceLookup,但它并不能提供打印机是否打开的状态。
另外,如果在Java中不可能实现,是否有任何在Windows中运行的命令可以给出打印机的状态?
然后,我可以在Java中运行此命令并检查状态。
snmpget
。语法如下:snmpget -v1 -c public host-ip OID
snmpget -v1 -c public 192.168.1.10 iso.3.6.1.2.1.43.17.6.1.5.1.2
并返回
iso.3.6.1.2.1.43.17.6.1.5.1.2 = STRING: "Ready"
使用OID可以返回我的惠普打印机状态。但是如果我在佳能打印机上使用相同的OID,我会得到
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: iso.3.6.1.2.1.43.17.6.1.5.1.2
boolean available = false;
try {
String serverAddress = "192.168.1.10";
Socket s = new Socket(serverAddress, 9100);
s.close();
available = true;
} catch (IOException e) {
available = false;
}
System.out.println("printer available: " + available);
当然,这仅在您已经知道打印机的 IP 地址时才有效。
import java.io.IOException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
public class PrinterStatus {
public static void main(String[] args) {
PrintService printer = PrintServiceLookup.lookupDefaultPrintService();
AttributeSet att = printer.getAttributes();
String ip = "0.0.0.0"; // IP Address of your printer
boolean check = false;
for (Attribute a : att.toArray()) {
if (att.get(a.getClass()).toString().equalsIgnoreCase("accepting-jobs")){
check = true;
}
}
if (check && runSystemCommand(ip)) System.out.println("Printer ready!");
}
public static boolean runSystemCommand(String ip) {
ProcessBuilder pb = new ProcessBuilder("ping", "-c 1", ip);
Process p;
try {
p = pb.start();
return p.waitFor() == 0 ? true : false;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
}
}
https://msdn.microsoft.com/en-us/library/windows/desktop/dd162752(v=vs.85).aspx
call OpenPrinter2() then ClosePrinter()
通过一些JNI代码,这将变得微不足道,您可能还想考虑使用https://github.com/java-native-access/jna使本地访问部分的代码更容易。
Win32_Printer
(https://msdn.microsoft.com/en-us/library/aa394363(v=vs.85).aspx)。一个旧的CodeProject网站展示了如何使用Win32_Printer
在C#中测试脱机打印机(http://www.codeproject.com/Articles/6069/How-to-Check-if-your-Printer-is-Connected-using-C)。
这个人(http://henryranch.net/software/jwmi-query-windows-wmi-from-java/)开发了jWMI,可以在Java中查询WMI系统,因此这可能适用于您的情况。我不确定它有多全面,但您可以想象它可以访问Win32_Printer
。它使用VBScript,在Java中通过cmd.exe
执行并从stdout
获取值,所以我不知道速度如何,但他还谈到了使用WMIC.exe,这可能更适合您。
从他的介绍中看来,您的代码可能非常简单:
String status = getWMIValue("Select [printer name] from Win32_Printer", "PrinterStatus");
其中7 (0x7)为离线状态。
或者
String status = getWMIValue("Select [printer name] from Win32_Printer", "Availability");
在其中可以识别各种状态(例如0x7 = 关机,或0x8 = 离线等)。
查询还允许使用“Select * from”语法,因此如果没有名称,您可以循环遍历打印机。
Win32_Printer
具有一个属性(Network
作为布尔值),允许您检查打印机是本地还是网络,并且这是一个旧但有趣的VBScript测试网络打印机的阅读材料(http://blogs.technet.com/b/heyscriptingguy/archive/2006/08/14/how-can-i-list-all-the-printers-on-a-remote-computer.aspx)。
这些解决方案已经过时了(我相信MI是WMI的最新版本),但如果jWMI库适合您,它可能是一个答案。
PrinterStatus
也会显示出来。 - Ambie我已经使用了
String WorkOffline = getWMIValue("Select *
from Win32_Printer
where Name='printer_name'", "WorkOffline");
returns True/False
PrintService
上的PrinterIsAcceptingJobs
属性吗? - clstrfsck