如果PC连接到网络打印机,如何检查java?

时间:2015-10-14 03:58:12

标签: java network-printers

基本上,我需要检查n / w打印机的状态,如果它打开或不打开。在java中有没有办法做到这一点?

是否有任何第三方API或工具?

我尝试在java中使用PrintServiceLookup,但是如果它打开或不打开它就不会给出状态。

另外,如果在java中不可能,是否有任何可以在Windows中运行的命令可以提供打印机的状态?

然后我可以在java中运行此命令并检查。

6 个答案:

答案 0 :(得分:3)

根据“How Network Printing Works”,它实际上取决于打印机的类型和它支持的协议。如果您知道打印机使用的IP和端口,并且您的打印机支持SNMP(仅选择协议),则可以使用SNMP协议1查询打印机以获取信息。 Java lib SNMP4j可以帮助您实现这一目标。除非打印机 ip 端口永远不会(!)更改您的设置,否则我建议不要使用它。这是因为你可能遇到几个问题

  • 如何发现未知的打印机?
  • 如何发现打印机使用的端口?
  • 如何发现打印机使用的协议?

让我们假设上面的问题不是什么大问题,并假设每台打印机都支持SNMP。如何从中获取信息?除了使用上面提到的java lib之外,您还可以从终端使用linux中的snmpget。语法如下:

snmpget -v1 -c public host-ip OID

OID是object identifier,适用于打印机的每个属性,从 pagecount 碳粉卡信息。如果您不添加OID,您将获得可用OID的完整列表。问题的关键在于,虽然所有OID都是标准化的,但OID的使用因品牌和打印机型号而异。对于我的HP,以下工作:

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返回HP的打印机状态。但如果我在佳能上使用相同的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

因此,它甚至不是SNMP一般适用的,也没有提及其他可用的协议。

考虑到所有这些信息,我认为最简单的方法就是检查您是否可以通过此代码在其中一个公共打印机端口上建立与打印机的连接

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的情况下才有效。

答案 1 :(得分:2)

如果您知道自己的打印机IP,可以使用此代码对其进行ping操作并检查它是否接受了工作。

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;
  }
}

当然,您需要稍微更改此代码才能在您的情况下使用它。 除了原生访问,我没有看到更好的解决方案。

答案 2 :(得分:1)

我不认为Java会为您提供任何可移植的API来检查状态。根据您的要求,您可能需要检查windows api

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来更轻松地访问代码的本机部分

答案 3 :(得分:1)

我无法想到在java中执行此操作的简单方法(毫无疑问,有人会想出一行代码!)。我对C#更熟悉,为了回答您的Windows问题,我使用了Microsoft的WMI,特别是Win32_Printerhttps://msdn.microsoft.com/en-us/library/aa394363(v=vs.85).aspx)。旧的CodeProject网站显示了如何使用Win32_Printerhttp://www.codeproject.com/Articles/6069/How-to-Check-if-your-Printer-is-Connected-using-C)在C#中测试脱机打印机。

它可能适用于你的情况,因为这个人(http://henryranch.net/software/jwmi-query-windows-wmi-from-java/)已经生成了jWMI,它可以在java中查询WMI系统。我不确定它有多详尽,但您可以想象它可以访问Win32_Printer。它使用VBScript,它通过cmd.exe在java中执行,并从stdout获取值,所以我不知道速度,但他也谈到使用可能更适合你的WMIC.exe。 / p>

从他的模糊中看,你的代码看起来就像以前一样直截了当:

String status = getWMIValue("Select [printer name] from Win32_Printer", "PrinterStatus");

其中7(0x7)处于离线状态。

String status = getWMIValue("Select [printer name] from Win32_Printer", "Availability");

可以消除各种状态(例如0x7 =断电,或0x8 =离线等)

查询还允许"选择*来自"如果你没有名字,你可以循环使用打印机。

Win32_Printer有一个属性(Network为布尔值),可以让您检查打印机是本地打印机还是网络打印机,这个(http://blogs.technet.com/b/heyscriptingguy/archive/2006/08/14/how-can-i-list-all-the-printers-on-a-remote-computer.aspx)是旧的,但很有趣,读取在VBScript中测试网络打印机。

这些解决方案相当长(例如,我认为MI是WMI的最新版本),但如果jWMI库可以为您工作,那么它可能就是答案。

答案 4 :(得分:1)

原生印刷设备有java api !!看看这堂课 java.awt.Desktop
java2s.com e.g

答案 5 :(得分:-1)

我用过

String WorkOffline = getWMIValue("Select * 
from Win32_Printer 
where Name='printer_name'", "WorkOffline");
returns True/False