Мога ли да проверя дали COM порт може да бъде отворен, без всъщност да го отварям?

Обикновено на компютър има някакъв нестандартен набор от COM портове, достъпни за използване от терминален емулатор. Бих искал да мога да сканирам портове COM1-COM32, за да видя кой (ако има такъв) от тези портове може да бъде отворен като сериен порт. Мога да направя това, като просто извикам CreateFile() на всички тези портове; тогава обаче всъщност трябва да отворя/затворя (и да повлияя на DTR/RTS) порта моментално.

Искам да предоставя точен списък на потребителя на наличните портове. Проблемът е, че не искам да засягам DTR/RTS линиите на портовете, които в момента не се използват, защото може да има хардуер, свързан към тези портове, който не иска да вижда никакъв преход на DTR/RTS.

Има ли начин просто да зададете въпроса: "Ще успее ли CreateFile()?" на определени com портове?


person Ed.    schedule 04.06.2009    source източник


Отговори (3)


Няколко начина

a) QueryDosDevice() - проверка за COM в имената

b) GetDefaultCommConfig() - Преминете през всички възможни серийни имена, напр. опитайте да получите конфигурация за COM1, COM2, ... COMn

c) HKLM/HARDWARE/DEVICEMAP/SERIALCOMM - Изброяване на ключовете

d) SetupAPI - ако си спомнях как да използвам това, без да се консултирам задълбочено с справочното ръководство, нямаше да съм човек

e) ???

Редактирано: както отбеляза Питър, освен изброяването, няма функция, която да ви каже дали имате достъп до устройството или не.

person Marko Teiste    schedule 04.06.2009
comment
Единственият, за който знам тук, е GetDefaultCommConfig() и въпреки че API е достатъчно прост, досега не успях да го накарам да се върне успешно. Има ли уловка? Това е просто низ, последван от указател към структура, последван от указател към попълнена стойност на размера (на структурата). Изглежда достатъчно просто, но не можах да го накарам да работи. Благодаря, - person Ed.; 05.06.2009
comment
Кодовият фрагмент, който използвам, следва... Ако видите нещо нередно, извикайте! :-) void somefunc(void) { COMMCONFIG cc; DWORD bsize = sizeof(COMMCONFIG); if (GetDefaultCommConfig(COM1,&cc,&bsize) == 0) { ShowLastError(GetDefaultCommConfig()); връщане; } ... } - person Ed.; 05.06.2009
comment
Изглежда подходът HKLM/HARDWARE/DEVICEMAP/SERIALCOMM работи най-добре! Благодаря много на теб и Серж! - person Ed.; 06.06.2009
comment
Само защото нещо работи, не означава, че трябва да го правите. API за настройка (семейство от функции SetupDiXXX) е правилният, документиран начин за изброяване на устройства в Windows. - person Peter Ruderman; 08.06.2009
comment
Това не е отговор на въпрос дали може да се отвори COM порт. Съществуващият порт, върнат от тези методи, може да е зает и няма да можете да го отворите. - person Kamil; 29.12.2020

Не, няма как да се зададе такъв въпрос. Отговорът така или иначе не би бил смислен. Дори операционната система да определи, че отварянето на COM порт ще успее в даден момент, това не означава, че можете да го отворите по-късно. (Може да се отвори например от друго приложение.) Можете да използвате функциите SetupDiXXX, за да изброите COM портовете в системата, но това всъщност само връща информация за инсталираните и активни драйвери. Не предоставя гаранции извън това.

person Peter Ruderman    schedule 04.06.2009
comment
На теория съм съгласен; в моята ситуация обаче мога спокойно да приема, че WinPC обикновено е за един потребител и бързото ненатрапчиво сканиране на наличността на порта е полезно нещо. Особено ако имате комбинация от реални COM портове и някои USB портове, където стойностите на COMX няма да са съседни. Благодаря - person Ed.; 05.06.2009

HKLM/HARDWARE/DEVICEMAP/SERIALCOMM е любимият ми.

това решение показва най-доброто съотношение лекота на внедряване спрямо точност IMO.

В повечето случаи е достатъчно точен, въпреки че съм виждал поне един производител на USB към серийни портове, чиято HW не винаги е включена там (FTDI IIRC).

person Serge Wautier    schedule 04.06.2009