简体   繁体   English

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

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

Basically, I need to check the status of the n/w printer, if its on or not. 基本上,我需要检查n / w打印机的状态,如果它打开或不打开。 Is there any way to do this in java? 在java中有没有办法做到这一点?

Is there any third party API or tool for this? 是否有任何第三方API或工具?

I tried using PrintServiceLookup in java, but it does not give the status, if its on or not. 我尝试在java中使用PrintServiceLookup,但它不提供状态,如果它打开或不打开。

Also, if its not possible in java, is there any command that can be run in windows that will give the status of the printer? 此外,如果在java中不可能,是否有任何命令可以在Windows中运行,将提供打印机的状态?

Then I can run this command in java and check. 然后我可以在java中运行这个命令并检查。

According to " How Network Printing Works " it really depends on the type of printer and the protocol which it supports. 根据“ 网络打印如何工作 ”,它实际上取决于打印机的类型和它支持的协议。 If you know the ip and the port used by you printer and if your printer supports SNMP (just to pick a protocol) you can use the SNMP protocoll to query your printer for information. 如果您知道打印机使用的IP和端口,并且您的打印机支持SNMP (仅选择协议),则可以使用SNMP协议1查询打印机以获取信息。 There is the Java lib SNMP4j which can help you achive this. Java lib SNMP4j可以帮助您实现这一目标。 I would suggest to not use it unless the printer , the ip and the port will never (!) change for your setup. 我建议不要使用它,除非打印机IP端口永远不会(!)更改您的设置。 This is because you can run into several problems 这是因为你可能遇到几个问题

  • How to discover an unknown printer ? 如何发现未知的打印机?
  • How to discover the port used by the printer ? 如何发现打印机使用的端口?
  • How to discover the protocoll used by the printer ? 如何发现打印机使用的协议?

Lets assume the questions above wouldn't be much of a problem and lets assume every printer would support SNMP. 让我们假设上面的问题不是什么大问题,并假设每台打印机都支持SNMP。 How to get informations out of it ? 如何从中获取信息? Besides using the mentioned java lib, you can use snmpget in linux from an terminal. 除了使用上面提到的java lib之外,您还可以在终端中使用linux中的snmpget The syntax is as follows: 语法如下:

snmpget -v1 -c public host-ip OID

The OID is an object identifier for every property of you printer reaching from pagecount to toner-cardridge information. OID是打印机从pagecount碳粉卡信息的每个属性的对象标识符 If you don't add an OID you'll get the whole list of available OID's. 如果您不添加OID,您将获得可用OID的完整列表。 The crux of the matter is although all OID's are standardized the usage of the OID's differ from brand to brand and from printer-model to printer-model. 问题的关键在于,虽然所有OID都是标准化的,但OID的使用因品牌和打印机型号而异。 For my HP the following works: 对于我的惠普,以下作品:

snmpget -v1 -c public 192.168.1.10 iso.3.6.1.2.1.43.17.6.1.5.1.2

and returns 并返回

iso.3.6.1.2.1.43.17.6.1.5.1.2 = STRING: "Ready"

the use OID returns the status of the printer for my HP. 使用OID返回HP的打印机状态。 But if I use the same OID on my Canon I'll get 但如果我在佳能上使用相同的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

Therefore it is not even SNMP generically applicable, not mentioning the other protocols which are available. 因此,它甚至不是SNMP一般适用的,也没有提到其他可用的协议。

Considering all these information, the easiest way in my opinition is just check if you can establish the connection to the printer on one of the common printer ports via this code 考虑到所有这些信息,我认为最简单的方法就是检查是否可以通过此代码在其中一个公共打印机端口上建立与打印机的连接

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

Of course this only works if you already know the printer ip. 当然,这只有在你已经知道打印机ip的情况下才有效。

If you know your printer IP you could use this code to ping it and check if it's accepting jobs. 如果您知道您的打印机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;
  }
}

Of course you need to change this code a little to use it in your case. 当然,您需要稍微更改此代码以便在您的情况下使用它。 Except native accessing, I don't see better solution. 除了本机访问,我没有看到更好的解决方案。

I don't think Java provide any portable API for you to check the status. 我认为Java不提供任何便携式API来检查状态。 Based on your requirement, you may want to check the windows api 根据您的要求,您可能需要检查windows api

https://msdn.microsoft.com/en-us/library/windows/desktop/dd162752(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/dd162752(v=vs.85).aspx

call OpenPrinter2() then ClosePrinter() 

with a little of JNI codes this will be trivial, you may also want to consider https://github.com/java-native-access/jna to make the native accessing part of your code easier 使用一些JNI代码,这将是微不足道的,您可能还需要考虑https://github.com/java-native-access/jna ,以便更轻松地访问代码的本机部分

I can't think of an easy way to do this in java (no doubt someone will come up with a single line of code though!). 我想不出在java中这么简单的方法(毫无疑问,有人会提出一行代码!)。 I'm more familiar with C# and, to answer your Windows question, I'd use Microsoft's WMI, specifically Win32_Printer ( https://msdn.microsoft.com/en-us/library/aa394363(v=vs.85).aspx ). 我对C#比较熟悉,为了回答你的Windows问题,我会使用微软的WMI,特别是Win32_Printerhttps://msdn.microsoft.com/en-us/library/aa394363 ( v= Win32_Printer )。 aspx )。 An old CodeProject site shows how to test for an offline printer in C# using Win32_Printer ( http://www.codeproject.com/Articles/6069/How-to-Check-if-your-Printer-is-Connected-using-C ). 一个旧的CodeProject站点显示了如何使用Win32_Printer在C#中测试脱机打印机( http://www.codeproject.com/Articles/6069/How-to-Check-if-your-Printer-is-Connected-using-C )。

It might work in your case because this guy ( http://henryranch.net/software/jwmi-query-windows-wmi-from-java/ ) has produced jWMI which can query the WMI systems in java. 它可能适用于你的情况,因为这个人( http://henryranch.net/software/jwmi-query-windows-wmi-from-java/ )已经生成了jWMI,它可以在java中查询WMI系统。 I'm not sure how exhaustive it is, but you'd imagine it could access Win32_Printer . 我不确定它是多么详尽,但你可以想象它可以访问Win32_Printer It uses VBScript which it executes within java via cmd.exe and obtains values from stdout so I've no idea about speed, but he also talks about using WMIC.exe which might suit you better. 它使用VBScript,它通过cmd.exe在java中执行,并从stdout获取值,所以我不知道速度,但他也谈到使用可能更适合你的WMIC.exe。

From his blurb, it looks as if your code could be as straight forward as: 从他的模糊,看起来你的代码可能像以下一样直截了当:

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

where 7 (0x7) is offline. 其中7(0x7)处于脱机状态。

or 要么

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

where various states can be discerened (such as 0x7 = power off, or 0x8 = off line, etc.) 可以消除各种状态(例如0x7 =断电,或0x8 =离线等)

The queries also allow a "Select * from" syntax so you could loop through the printers if you didn't have a name. 查询还允许“Select * from”语法,以便在没有名称的情况下循环打印机。

Win32_Printer has a property ( Network as Boolean) that allows you to check whether the printer is local or network, and this ( http://blogs.technet.com/b/heyscriptingguy/archive/2006/08/14/how-can-i-list-all-the-printers-on-a-remote-computer.aspx ) is an old, but interesting, read on testing for a network printer in VBScript. 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中测试网络打印机。

These solutions are pretty long in the tooth (I believe MI is the most recent version of WMI, for example), but if that jWMI library can work for you, it might be an answer. 这些解决方案非常长(例如,我认为MI是WMI的最新版本),但如果jWMI库可以为您工作,那么它可能就是一个答案。

there is java api to native printing facility !! 原生打印设备有java api !! check out this class java.awt.Desktop 看看这个类java.awt.Desktop
java2s.com eg java2s.com 例如

i have used 我用过

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