1

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: enter image description here

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.

Arman21
  • 93
  • 1
  • 3
  • 16
  • check the implementing classes here to see which attributes might exist for printer service attribute the https://docs.oracle.com/javase/8/docs/api/javax/print/attribute/PrintServiceAttribute.html – Kai Iskratsch Jan 22 '16 at 09:11
  • for attributes.get you most likely will have to use https://docs.oracle.com/javase/8/docs/api/javax/print/attribute/standard/PrinterState.html#getName-- – Kai Iskratsch Jan 22 '16 at 09:15
  • It seems duplicate http://stackoverflow.com/questions/16035739/how-to-access-the-status-of-the-printer – Pankaj Pandey Jan 22 '16 at 09:18

2 Answers2

2

Windows only solution, query WMI "win32_printer" class: Win32_Printer class.

In Java you can use ProcessBuilder like this to start PowerShell and execute the PS script:

    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.

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 e.g. for Epson printers you must use "ESDPRT" and not COM or LPT directly for states updating correctly...

If states work, parse the numbers and make your program work accordingly, e.g. State = 4240 and Status = 3 means "No paper" for Epson (TM) printers...

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:

  • StatusInfo
  • Status
  • Availability
  • ErrorDescription
  • ErrorInformation
  • ExtendedDetectedErrorState
  • ExtendedPrinterStatus
  • ...
Rok T.
  • 301
  • 3
  • 7
-1

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. You need to configure it in windows and depending on the environment this could be a problem.