繁体   English   中英

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

[英]How to check in java if the PC is connected to the network printer?

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

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

我尝试在java中使用PrintServiceLookup,但它不提供状态,如果它打开或不打开。

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

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

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

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

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

snmpget -v1 -c public host-ip OID

OID是打印机从pagecount碳粉卡信息的每个属性的对象标识符 如果您不添加OID,您将获得可用OID的完整列表。 问题的关键在于,虽然所有OID都是标准化的,但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返回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_Printerhttps://msdn.microsoft.com/en-us/library/aa394363 ( v= Win32_Printer )。 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM