[英]How to check in java if the PC is connected to the network printer?
基本上,我需要檢查n / w打印機的狀態,如果它打開或不打開。 在java中有沒有辦法做到這一點?
是否有任何第三方API或工具?
我嘗試在java中使用PrintServiceLookup,但它不提供狀態,如果它打開或不打開。
此外,如果在java中不可能,是否有任何命令可以在Windows中運行,將提供打印機的狀態?
然后我可以在java中運行這個命令並檢查。
根據“ 網絡打印如何工作 ”,它實際上取決於打印機的類型和它支持的協議。 如果您知道打印機使用的IP和端口,並且您的打印機支持SNMP (僅選擇協議),則可以使用SNMP協議1查詢打印機以獲取信息。 Java lib SNMP4j可以幫助您實現這一目標。 我建議不要使用它,除非打印機 , IP和端口永遠不會(!)更改您的設置。 這是因為你可能遇到幾個問題
讓我們假設上面的問題不是什么大問題,並假設每台打印機都支持SNMP。 如何從中獲取信息? 除了使用上面提到的java lib之外,您還可以在終端中使用linux中的snmpget
。 語法如下:
snmpget -v1 -c public host-ip OID
OID是打印機從pagecount到碳粉卡信息的每個屬性的對象標識符 。 如果您不添加OID,您將獲得可用OID的完整列表。 問題的關鍵在於,雖然所有OID都是標准化的,但OID的使用因品牌和打印機型號而異。 對於我的惠普,以下作品:
snmpget -v1 -c public 192.168.1.10 iso.3.6.1.2.1.43.17.6.1.5.1.2
並返回
iso.3.6.1.2.1.43.17.6.1.5.1.2 = STRING: "Ready"
使用OID返回HP的打印機狀態。 但如果我在佳能上使用相同的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
因此,它甚至不是SNMP一般適用的,也沒有提到其他可用的協議。
考慮到所有這些信息,我認為最簡單的方法就是檢查是否可以通過此代碼在其中一個公共打印機端口上建立與打印機的連接
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);
當然,這只有在你已經知道打印機ip的情況下才有效。
如果您知道您的打印機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;
}
}
當然,您需要稍微更改此代碼以便在您的情況下使用它。 除了本機訪問,我沒有看到更好的解決方案。
我認為Java不提供任何便攜式API來檢查狀態。 根據您的要求,您可能需要檢查windows api
https://msdn.microsoft.com/en-us/library/windows/desktop/dd162752(v=vs.85).aspx
call OpenPrinter2() then ClosePrinter()
使用一些JNI代碼,這將是微不足道的,您可能還需要考慮https://github.com/java-native-access/jna ,以便更輕松地訪問代碼的本機部分
我想不出在java中這么簡單的方法(毫無疑問,有人會提出一行代碼!)。 我對C#比較熟悉,為了回答你的Windows問題,我會使用微軟的WMI,特別是Win32_Printer
( https://msdn.microsoft.com/en-us/library/aa394363 ( v= Win32_Printer
)。 aspx )。 一個舊的CodeProject站點顯示了如何使用Win32_Printer
在C#中測試脫機打印機( http://www.codeproject.com/Articles/6069/How-to-Check-if-your-Printer-is-Connected-using-C )。
它可能適用於你的情況,因為這個人( http://henryranch.net/software/jwmi-query-windows-wmi-from-java/ )已經生成了jWMI,它可以在java中查詢WMI系統。 我不確定它是多么詳盡,但你可以想象它可以訪問Win32_Printer
。 它使用VBScript,它通過cmd.exe
在java中執行,並從stdout
獲取值,所以我不知道速度,但他也談到使用可能更適合你的WMIC.exe。
從他的模糊,看起來你的代碼可能像以下一樣直截了當:
String status = getWMIValue("Select [printer name] from Win32_Printer", "PrinterStatus");
其中7(0x7)處於脫機狀態。
要么
String status = getWMIValue("Select [printer name] from Win32_Printer", "Availability");
可以消除各種狀態(例如0x7 =斷電,或0x8 =離線等)
查詢還允許“Select * from”語法,以便在沒有名稱的情況下循環打印機。
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中測試網絡打印機。
這些解決方案非常長(例如,我認為MI是WMI的最新版本),但如果jWMI庫可以為您工作,那么它可能就是一個答案。
原生打印設備有java api !! 看看這個類java.awt.Desktop
java2s.com 例如
我用過
String WorkOffline = getWMIValue("Select *
from Win32_Printer
where Name='printer_name'", "WorkOffline");
returns True/False
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.