I am able to get the name of printer which I had installed previously on my PC.But now its not physically connected to my pc. How should I check it first before moving to Print(
Take a look at the javax.print API. A good starting point would be PrintServiceLookup.
There is no PrinterState Attribute in Set. But you can load library Winspool.drv and ask it for attributes. There is int Attributes@68=, which has a40 value for online and e40 value for offline printer.
Start there - https://msdn.microsoft.com/cs-cz/library/windows/desktop/dd144911(v=vs.85).aspx .
Use these classes and then get WinspoolUtilExt.getPrinterInfo2(ps.getName()).toString() and there is an attribute.
public interface WinspoolExt extends Winspool {
WinspoolExt INSTANCE = (WinspoolExt) Native.loadLibrary("Winspool.drv", WinspoolExt.class, W32APIOptions.UNICODE_OPTIONS);
boolean GetPrinter(HANDLE hPrinter, int Level, Pointer pPrinter, int cbBuf, IntByReference pcbNeeded);
boolean OpenPrinter(String pPrinterName, HANDLEByReference phPrinter, Pointer pDefault);
public static class PRINTER_INFO_2 extends Structure {
public String pServerName;
public String pPrinterName;
public String pShareName;
public String pPortName;
public String pDriverName;
public String pComment;
public String pLocation;
public INT_PTR pDevMode;
public String pSepFile;
public String pPrintProcessor;
public String pDatatype;
public String pParameters;
public INT_PTR pSecurityDescriptor;
public int Attributes;
public int Priority;
public int DefaultPriority;
public int StartTime;
public int UntilTime;
public int Status;
public int cJobs;
public int AveragePPM;
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "pServerName", "pPrinterName", "pShareName", "pPortName", "pDriverName", "pComment", "pLocation", "pDevMode", "pSepFile", "pPrintProcessor", "pDatatype", "pParameters", "pSecurityDescriptor", "Attributes", "Priority", "DefaultPriority", "StartTime", "UntilTime", "Status", "cJobs", "AveragePPM" });
}
public PRINTER_INFO_2() {
}
public PRINTER_INFO_2(int size) {
super(new Memory(size));
}
}
}
public class WinspoolUtilExt extends WinspoolUtil {
public static PRINTER_INFO_2 getPrinterInfo2(String printerName) {
IntByReference pcbNeeded = new IntByReference();
IntByReference pcReturned = new IntByReference();
HANDLEByReference pHandle = new HANDLEByReference();
WinspoolExt.INSTANCE.OpenPrinter(printerName, pHandle, (Pointer) null);
WinspoolExt.INSTANCE.GetPrinter(pHandle.getValue(), 2, null, 0, pcbNeeded);
if (pcbNeeded.getValue() <= 0) {
return new PRINTER_INFO_2();
}
PRINTER_INFO_2 pinfo2 = new PRINTER_INFO_2(pcbNeeded.getValue());
WinspoolExt.INSTANCE.GetPrinter(pHandle.getValue(), 2, pinfo2.getPointer(), pcbNeeded.getValue(), pcReturned);
pinfo2.read();
return (PRINTER_INFO_2) pinfo2;
}
}
Maven dependencies:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>${jna.version}</version>
</dependency>
Another way is to use PowerShell and query:
Get-WmiObject -Query "Select * From Win32_PnPEntity where deviceid like 'USBPRINT\\%' and caption like '%Canon%'"
This way, you get result only if printer is connected.
You can query WMI from Java with many libraries, search "WMI Java library".
You can use PrinterState
attribute if it is supported by your printer.
Something like this:
PrintServiceAttributeSet printServiceAttributes = selectedService.getAttributes();
PrinterState printerState = (PrinterState) printServiceAttributes.get(PrinterState.class);
if (printerState != null){
System.out.println(printerName + " is online");
}
else {
System.out.println(printerName + " is offline");
}