Я достиг того, что хотел, используя класс WinRegistry
, предоставленный Дэвидом в этом вопросе SO , чтобы получить FriendlyName из раздела реестра, связанного с моим USB-устройством. Затем я анализирую номер COM из понятного имени.
Некоторые вещи, которые следует учитывать:
USB-устройства находятся в реестре HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\
(протестировано на WinXP, Win7.)
Мне потребовалось, чтобы VID + PID устройства идентифицировал правильный ключ устройства (например, VID_xxxx&PID_xxxx
.) Поскольку VID и PID зависят от устройства, этот ключ должен быть надежным во многих системах.
Клавиша VID_xxxx&PID_xxxx
содержит еще один подраздел с параметрами устройства. У меня были некоторые проблемы при перечислении подключей с помощью WinRegistry
, поэтому я жестко закодировал имя подключа как быстрый взлом во время разработки. Гораздо более безопасное решение будет искать подключи, чтобы найти правильное имя.
Ключи устройства существуют в реестре независимо от того, подключено ли устройство в данный момент. Этот код предполагает, что Windows обновит FriendlyName , если устройство будет повторно подключено к другому COM-порту. Я не проверял это, но все выглядело хорошо во время тестирования использования.
Пример * +1034 *
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;
}