简体   繁体   English

Java:如何检查打印机状态

[英]Java: How to check if printer status

I'm looking for a method to check some Status from my Printer. 我正在寻找一种检查打印机状态的方法。 I'd like to know These Status: 我想知道以下状态:

  • If Printer is on / off 如果打印机开/关
  • If paper is out 如果缺纸
  • Maybe a way to get Default paper size? 也许是一种获取默认纸张尺寸的方法?

I've found this code part: 我发现此代码部分:

Attribute[] attrs = service.getAttributes().toArray();

for (Attribute attr : attrs) {
    String attrName = attr.getName();
    String attrValue = attr.toString();

    System.out.println("Found attribute: " + attrName + " with value: " + attrValue);
}

This part works fine and gives me this Output: 这部分工作正常,并提供以下输出: 在此处输入图片说明

But I didn't found a way to get the Information I want. 但是我没有找到获取所需信息的方法。

I've also tried this. 我也试过了。

AttributeSet attributes = service.getAttributes();
String printerState = attributes.get(PrinterState.class).toString();

System.out.println("printerState = " + printerState); 

But printerState is always null . 但是printerState始终为null

Windows only solution, query WMI "win32_printer" class: Win32_Printer class . 仅Windows解决方案,查询WMI“ win32_printer”类: Win32_Printer类

In Java you can use ProcessBuilder like this to start PowerShell and execute the PS script: 在Java中,您可以像这样使用ProcessBuilder来启动PowerShell并执行PS脚本:

    String printerName = "POS_PRINTER";
    ProcessBuilder builder = new ProcessBuilder("powershell.exe", "get-wmiobject -class win32_printer | Select-Object Name, PrinterState, PrinterStatus | where {$_.Name -eq '"+printerName+"'}");

    String fullStatus = null;
    Process reg;
    builder.redirectErrorStream(true);
    try {
        reg = builder.start();
        fullStatus = getStringFromInputStream(reg.getInputStream());
        reg.destroy();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    System.out.print(fullStatus);

For getStringFromInputStream() method have a look here: a comprehensive StackOverflow answer . 对于getStringFromInputStream()方法,请看这里: 全面的StackOverflow答案

After running the above code, you will get a string with content something like this: 运行上面的代码后,您将获得一个字符串,其内容如下:

Name        PrinterState PrinterStatus
----        ------------ -------------
POS_PRINTER            0             3

You now need to see if state and status codes are changing for various printer states - turn off the printer and check the numbers, open cover, remove paper, etc,... This is I think manufacturer/driver dependent so you simply need to test and see the return codes. 现在,您需要查看各种打印机状态的状态和状态代码是否正在更改-关闭打印机并检查编号,打开机盖,取出纸张等,...我认为这取决于制造商/驱动程序,因此您只需要测试并查看返回码。 It might also be important that the correct printer port is used eg for Epson printers you must use "ESDPRT" and not COM or LPT directly for states updating correctly... 使用正确的打印机端口也可能很重要,例如对于Epson打印机,必须使用“ ESDPRT”而不是COM或LPT来直接正确更新状态。

If states work, parse the numbers and make your program work accordingly, eg State = 4240 and Status = 3 means "No paper" for Epson (TM) printers... 如果状态有效,则解析数字并使程序相应地工作,例如,State = 4240和Status = 3表示对于Epson(TM)打印机为“无纸” ...

If things work, you can parse status and state code like this: 如果一切正常,您可以像下面这样解析状态和状态代码:

    int statusCode = 0;
    int stateCode = 0;
    int indexPrinterStatusCodeStart = fullStatus.length() - 1;

    PrinterStatus printerStatus = null;

    // reverse loop string till space and remember index which indicates start of printerStatusCode
    while(fullStatus.charAt(indexPrinterStatusCodeStart) != ' '){ 
        indexPrinterStatusCodeStart--;
    }       
    try{
        // substring between indexPrinterStatusCode and string length
        statusCode=Integer.parseInt(fullStatus.substring(indexPrinterStatusCodeStart, fullStatus.length()).trim());

        // substring between index of printerName + printerName length and start index of printerStatusCode
        stateCode=Integer.parseInt(fullStatus.substring(fullStatus.indexOf(printerName) + printerName.length(), indexPrinterStatusCodeStart).trim());
    }catch(Exception e){
        System.err.println("Failed to parse printer status/state codes!" + e.getMessage());
    }

And then something like that... 然后像那样

    if(statusCode == 1 || statusCode == 2){
        if(statusCode == 1 && stateCode == 1){
            printerStatus = "Printer paused!";
        }else{
            printerStatus = "Printer turned off!";
        }
    }else if (statusCode == 3 && stateCode == 0){
        printerStatus = "Printer should work!";         
    }
    // etc...

Win32_Printer class also includes some other properties that might work for some other printers/drivers and are worth testing, properties like: Win32_Printer类还包括一些其他属性,这些属性可能适用于某些其他打印机/驱动程序,值得测试,这些属性包括:

  • StatusInfo StatusInfo
  • Status 状态
  • Availability 可用性
  • ErrorDescription ErrorDescription中
  • ErrorInformation ErrorInformation
  • ExtendedDetectedErrorState ExtendedDetectedErrorState
  • ExtendedPrinterStatus ExtendedPrinterStatus
  • ... ...

I am looking for the same printer information. 我正在寻找相同的打印机信息。 By default you only can get only the information you found. 默认情况下,您只能获取找到的信息。 If you need more you can use SNMP. 如果需要更多,可以使用SNMP。 You need to configure it in windows and depending on the environment this could be a problem. 您需要在Windows中进行配置,这可能是一个问题,具体取决于环境。

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

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