更新:
我建议不要像这样直接使用 Powershell,而不是查询 WMI“win32_printer”对象,它的 API 更简洁:
Get-Printer | where PrinterStatus -like 'Normal' | fl
查看所有打印机和状态:
Get-Printer | fl Name, PrinterStatus
查看所有属性:
Get-Printer | fl
您仍然可以在 Java 中使用 ProcessBuilder,如下所述。
更新前:
Windows解决方案,查询WMI“win32_printer”对象:
public static void main(String[] args) {
// select printer that have state = 0 and status = 3, which indicates that printer can print
ProcessBuilder builder = new ProcessBuilder("powershell.exe", "get-wmiobject -class win32_printer | Select-Object Name, PrinterState, PrinterStatus | where {$_.PrinterState -eq 0 -And $_.PrinterStatus -eq 3}");
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);
}
将 InputStream 转换为 String 看这里:comprehensive StackOverflow answer,或者你可以简单地使用:
public static String getStringFromInputStream(InputStream is) {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
try {
while ((length = is.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
} catch (IOException e1) {
e1.printStackTrace();
}
// StandardCharsets.UTF_8.name() > JDK 7
String finalResult = "";
try {
finalResult = result.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return finalResult;
}
输出:
Name PrinterState PrinterStatus
---- ------------ -------------
Foxit Reader PDF Printer 0 3
Send to OneNote 2010 0 3
Microsoft XPS Document Writer 0 3
Microsoft Print to PDF 0 3
Fax 0 3
\\192.168.50.192\POS_PRINTER 0 3
如您所见,您现在在字符串中拥有了所有处于工作状态的打印机。
您可以使用现有方法 (getAvailablePrinters()),例如添加如下内容:
ArrayList<String> workingPrinter = new ArrayList<String>();
System.out.println("Working printers:");
for(String printer : getAvailablePrinters()){
if(fullStatus.contains("\n" + printer + " ")){ // add a newline character before the printer name and space after so that it catches exact name
workingPrinter.add(printer);
System.out.println(printer);
}
}
现在您将获得一份不错的工作打印机列表。
控制台输出:
Working printers:
Send to OneNote 2010
Foxit Reader PDF Printer
Microsoft XPS Document Writer
Microsoft Print to PDF
Fax
\\192.168.50.192\POS_PRINTER
当然,您必须小心使用这种方法的名称 - 例如如果“POS_PRINTER”在所有打印机中但不在工作打印机列表中,它仍然可以添加到工作打印机列表中,如果有一个名为“POS_PRINTER 1”的工作打印机,因为该名称包含“\nPOS_PRINTER”字符串...