我有一个串口转 USB 设备,在 Windows 设备管理器中有一个类似名称的设备驱动程序。这些设备并不总是在系统启动时占用相同的 COM 端口,因此我的程序需要在启动时识别它。
我试过使用 RXTX枚举系统上的 COM 端口,但这没有用,因为 CommPortIdentifier.getName()
只是返回 COM 名称(例如 COM1、COM2 等)我需要获取驱动程序制造商名称或出现在设备管理器中的驱动程序名称,并将其与 COM 名称相关联。
这可以用 Java 轻松完成吗? (我会对支持此功能的任何第 3 方 Java 库感兴趣。)否则,我如何通过 win32 API 开始完成此操作?
最佳答案
我通过使用 David 在 this SO question 中提供的 WinRegistry
类实现了我想要的。从与我的 USB 设备关联的注册表项中获取 FriendlyName。然后我从友好名称中解析出 COM 编号。
一些需要考虑的事情:
USB 设备位于注册表中的
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\
(已在 WinXP、Win7 上测试。)我需要设备 VID + PID 来识别正确的设备 key (例如
VID_xxxx&PID_xxxx
。)由于 VID 和 PID 是特定于设备的,因此该 key 在多个系统中应该是可靠的。VID_xxxx&PID_xxxx
键包含另一个具有设备值的子键。我在使用WinRegistry
枚举子键时遇到了一些麻烦,因此我在开发过程中将子键名称硬编码为快速破解。一种更安全的解决方案是搜索子键以找到正确的名称。无论设备当前是否已连接,设备 key 都存在于注册表中。此代码假设如果设备重新连接到不同的 COM 端口,Windows 将更新 FriendlyName。我尚未对此进行验证,但在使用测试期间看起来一切正常。
例子
String keyPath = "SYSTEM\\CurrentControlSet\\Enum\\USB\\Vid_067b&Pid_2303\\";
String device1 = "5&75451e6&0&1";
System.out.println("First COM device: " + getComNumber(keyPath + device1));
代码
import java.util.regex.Pattern;
import java.util.regex.Matcher;
// Given a registry key, attempts to get the 'FriendlyName' value
// Returns null on failure.
//
public static String getFriendlyName(String registryKey) {
if (registryKey == null || registryKey.isEmpty()) {
throw new IllegalArgumentException("'registryKey' null or empty");
}
try {
int hkey = WinRegistry.HKEY_LOCAL_MACHINE;
return WinRegistry.readString(hkey, registryKey, "FriendlyName");
} catch (Exception ex) { // catch-all:
// readString() throws IllegalArg, IllegalAccess, InvocationTarget
System.err.println(ex.getMessage());
return null;
}
}
// Given a registry key, attempts to parse out the integer after
// substring "COM" in the 'FriendlyName' value; returns -1 on failure.
//
public static int getComNumber(String registryKey) {
String friendlyName = getFriendlyName(registryKey);
if (friendlyName != null && friendlyName.indexOf("COM") >= 0) {
String substr = friendlyName.substring(friendlyName.indexOf("COM"));
Matcher matchInt = Pattern.compile("\\d+").matcher(substr);
if (matchInt.find()) {
return Integer.parseInt(matchInt.group());
}
}
return -1;
}
关于java - 获取与 COM 端口相关的设备/驱动程序信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6362775/