Comment puis-je obtenir une liste des ports série disponibles dans Win32?

J’ai un code hérité qui fournit une liste des ports COM disponibles sur le PC en appelant la fonction EnumPorts() , puis en filtrant les noms de port commençant par “COM”.

À des fins de test, il serait très utile d’utiliser ce code avec quelque chose comme com0com , qui fournit des paires de ports COM virtuels regroupés en un null-modem.

Cependant, les ports com0com ne sont pas trouvés par la fonction EnumPorts() (même sans filtrage pour “COM”). HyperTerminal et SysInternals PortMon peuvent les voir tous les deux, donc je suis sûr qu’il est correctement installé.

Y a-t-il une autre fonction Win32 qui fournit une liste définitive des ports série disponibles?

Le EnumSerialPorts v1.20 proposé par Nick D utilise neuf méthodes différentes pour lister les ports série! Nous ne sums certainement pas à court de choix, même si les résultats semblent varier.

Pour éviter les problèmes, je vais les énumérer ici et indiquer leur succès dans la recherche des ports com0com sur mon PC (XP Pro SP2):

  1. CreateFile (“COM” + 1-> 255) comme suggéré par Wael Dalloul
    ✔ Les ports com0com trouvés, ont pris 234ms.

  2. QueryDosDevice ()
    ✔ Trouvé les ports com0com, a pris 0ms.

  3. GetDefaultCommConfig (“COM” + 1-> 255)
    ✔ Les ports com0com trouvés, ont pris 235ms.

  4. “SetupAPI1” utilisant des appels à SETUPAPI.DLL
    ✔ Trouvé ports com0com, également signalé “noms amicaux”, a pris 15ms.

  5. “SetupAPI2” utilisant des appels à SETUPAPI.DLL
    Find Je n’ai pas trouvé de ports com0com, rapportés “noms amicaux”, a pris 32ms.

  6. EnumPorts ()
    ✘ Signalé certains ports non COM, n’a pas trouvé les ports com0com, a pris 15ms.

  7. Utiliser les appels WMI
    ✔ Trouvé ports com0com, également signalé “noms amicaux”, a pris 47ms.

  8. Base de données COM utilisant les appels à MSPORTS.DLL
    ✔ / ed Signalé que certains ports non-COM, trouvé des ports com0com, ont pris 16ms.

  9. Itérer sur la clé de registre HKEY_LOCAL_MACHINE \ HARDWARE \ DEVICEMAP \ SERIALCOMM
    ✔ Trouvé les ports com0com, a pris 0ms. C’est apparemment ce que SysInternals PortMon utilise.

Sur la base de ces résultats, je pense que la méthode WMI convient probablement mieux à mes besoins car elle est relativement rapide et en prime, elle donne également des noms conviviaux (par exemple “Communications Port (COM1)”, “com0com – serial port emulator”).

Il semble que ce ne soit pas une tâche simple.

Découvrez ceci: EnumSerialPorts v1.20

vous pouvez faire une boucle par exemple de 1 à 50 et essayer d’ouvrir chaque port. Si le port est disponible, l’ouverture fonctionnera. Si le port est utilisé, vous obtenez une erreur de partage. Si le port n’est pas installé, vous obtiendrez une erreur de fichier introuvable.

pour ouvrir le port, utilisez l’API CreateFile :

 HANDLE Port = CreateFile( "\\\\.\\COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 

puis vérifiez le résultat.

J’ai réorganisé les EnumSerialPorts de PJ Naughter comme des formulaires plus portables et individuels, ce qui est plus utile.

Pour une meilleure compatibilité, j’utilise C au lieu de C ++.

Si vous en avez besoin ou si vous vous y intéressez, visitez le post de mon blogueur.

Dans mon cas, j’ai besoin à la fois des noms complets et des adresses de port COM. J’ai des ports série physiques, des ports série USB et des ports série virtuels comocom.

Comme le suggère la réponse acceptée, j’utilise les appels WMI. SELECT * FROM Win32_PnPEntity trouve tous les périphériques. Il retourne des périphériques physiques comme celui-ci et l’adresse peut être analysée à partir de la Caption :

 Serial Port for Barcode Scanner (COM13) 

Cependant, pour les ports com0com, la Caption est la suivante (pas d’adresse):

 com0com - serial port emulator 

SELECT * FROM Win32_SerialPort renvoie les adresses ( DeviceID ), ainsi que les noms complets ( Name ). Cependant, il ne trouve que des ports série physiques et des ports comOcom, pas des ports série USB.

Donc, à la fin, j’ai besoin de deux appels WMI: SELECT * FROM Win32_SerialPort (adresse est DeviceID ) et SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%' (l’adresse peut être analysée à partir de Caption ). , car il suffit de trouver les périphériques qui n’ont pas été trouvés lors du premier appel.