如何在PC连接网络打印机的情况下检查java



基本上,我需要检查n/w打印机的状态,是否打开。在java中有什么办法做到这一点吗?

是否有第三方API或工具?

我尝试在java中使用printservicellookup,但它没有给出状态,如果它打开或不打开。

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

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

根据"网络打印如何工作",这取决于打印机的类型和它支持的协议。如果您知道打印机使用的ip和端口,并且您的打印机支持SNMP(只是选择一个协议),那么您可以使用SNMP协议来查询打印机的信息。Java库SNMP4j可以帮助您实现这一点。我建议不要使用它,除非打印机ip端口在您的设置中永远不会(!)改变。这是因为您可能会遇到一些问题

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

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

snmpget -v1 -c public host-ip OID

OID是打印机的每个属性的对象标识符,从页号墨盒信息。如果您不添加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的情况下才有效。

如果您知道您的打印机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;
  }
}

当然,您需要稍微更改这段代码以在您的情况下使用它。除了本地访问,我找不到更好的解决方案。

我认为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,使您的代码的本机访问部分更容易

我想不出一个简单的方法在java中做到这一点(毫无疑问,有人会想出一行代码!)我更熟悉c#,为了回答你的Windows问题,我会使用微软的WMI,特别是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,它通过cmd.exe在java中执行,并从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为布尔值),允许您检查打印机是本地的还是网络的,这(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库可以为您工作,它可能是一个答案。

有Java API到本机打印设施!!看看这门课java.awt.Desktop
java2s.com如

我用

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

最新更新