WinRegistry通过在此SO问题中使用David提供的类,从与我的USB设备关联的注册表项中获取 FriendlyName
,我实现了所需的功能。然后,我从友好名称中解析出COM号。
要考虑的一些事情:
USB设备位于
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetEnumUSB
注册表中(在WinXP,Win7上经过测试)。我需要设备VID + PID来标识正确的设备密钥(例如..)
VID_xxxx&PID_xxxx
。由于VID和PID是特定于设备的,因此该密钥在多个系统之间应该是可靠的。该
VID_xxxx&PID_xxxx
键包含另一个具有设备值的子键。我在用枚举子密钥时遇到了一些麻烦WinRegistry
,因此我在开发过程中将子密钥名称硬编码为快速技巧。一种更安全的解决方案是搜索子项以找到正确的名称。不管设备当前是否连接,设备密钥都存在于注册表中。此代码假定如果设备重新连接到其他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;}


