2010-05-02 3 views
1

Dans mon application C# 2008, j'utilise la fonction SerialPort.GetPortNames() pour récupérer la liste des ports actuellement disponibles. Ce que j'ai remarqué est, quand je branche un périphérique USB, c'est le numéro de port indiqué dans la liste sur mon application et quand je le débranche et actualise la liste, le numéro de port n'est plus là.Comportement SerialPort.GetPortNames()

Une phase de l'application implique la lecture/écriture de données depuis/vers l'appareil en continu. Maintenant, mon attente est, Si je débranche le périphérique pendant l'opération et obtiens la liste actuelle de port en utilisant SerialPort.GetPortNames(), le nom de port ne sera pas là et je peux l'utiliser pour prendre la décision que le périphérique a été débranché.

À ma grande surprise, le nom du port se trouve encore, malgré l'avoir enlevé

Pourquoi le programme comporte comme celui-ci? Le nom du port n'est pas répertorié en mode sans communication. Cela a-t-il quelque chose à voir avec le retrait de l'appareil lorsqu'il communique?

Répondre

3

Je suppose que vous voulez dire System.IO.Ports.SerialPort.GetPortNames(), parce que je ne pouvais pas trouver une fonction GetPortList() n'importe où. MSDN dit: "Si le registre contient des données obsolètes ou incorrectes alors la méthode GetPortNames retournera des données incorrectes", c'est probablement là que réside le problème. Je suppose que Windows ne met pas à jour le registre si le port est encore 'utilisé', tout comme vous ne pouvez pas supprimer un fichier quand un programme a un handle dessus.

Si vous souhaitez tester si le périphérique est supprimé, vous pouvez le faire avec un appel API Window (http://www.pinvoke.net/default.aspx/user32/RegisterDeviceNotification.html). J'espère que cela pourra aider!

+0

Merci pour les suggestions. On dirait que Windows API est la meilleure solution. Je suis totalement inexpérimenté avec l'utilisation de Windows API. Vous supposez que j'ai de l'expérience en C#, pourriez-vous suggérer un lien d'où j'ai une bonne compréhension de l'utilisation de l'API Windows avec les applications C# 2008. –

+0

http://msdn.microsoft.com/en-us/magazine/cc164123.aspx aidera probablement. Cependant, je n'ai aucune expérience dans ce domaine. –

4

Vous avez pour parler de SerialPort.GetPortNames(), "GetPortList" n'a pas de sens. La fonction itère les valeurs dans le registre, écrites par votre pilote de périphérique USB. Vous pouvez avoir un look-voir avec Regedit.exe, naviguez vers HKLM \ Hardware \ DeviceMap \ SerialComm. Débranchez-le, appuyez sur F5, si le port COM est toujours là, alors SerialPort ne sait pas mieux que le port toujours présent.

Il n'y a aucun comportement prescrit quant à la façon dont un pilote de périphérique de port série doit se comporter lorsque le port disparaît soudainement. Les ports série sont très primitifs, ils remontent à une époque où "bug" signifiait un papillon gommant le télétype. Il n'y a aucune prise en charge matérielle pour Plug and Play, la suppression d'un port avec l'alimentation allumée équivaut à débrancher le lecteur de disque pendant que Windows est en train de basculer vers le fichier d'échange.

La plupart des pilotes de périphériques renvoient un code d'erreur, il génère une exception non détectable qui bloque votre programme. Le sujet de this feedback article. Apparemment, votre pilote de périphérique ne fait pas cela, ce qui devrait être préférable au bombardement de votre programme. Encourageant btw, la plupart des pilotes de périphériques d'émulation USB sont des indésirables.

La solution de contournement ultime est simple: mettre une petite étiquette sur la prise "ne pas déconnecter en cours d'utilisation!" C'est un peu un problème avec l'USB, la plupart des gens le regardent et vont "hmm, que puis-je faire avec?". Et arrivez à la seule réponse et débranchez-le. Après quelques kabooms, ils apprendront à ne plus faire ça.

+0

+1 pour notre dégoût mutuel pour les périphériques USB vers série. – Andy

1

Il est exact que GetPortNames() lit les ports de la clé de Registre

HKLM\Hardware\DeviceMap\SerialComm 

Ceci est automagiquement mis à jour par Windows à chaque fois qu'un port est ouvert ou fermé.

Mais néanmoins il m'est arrivé qu'il y ait un port inexistant répertorié dans le Registre, et est également revenu de GetPortNames(). Lorsque j'essaie d'ouvrir ce port, je reçois "Le port XYZ n'existe pas".

Qu'est-ce que c'est ???

J'ai maintenant trouvé la raison: Cela arrive toujours après avoir utilisé PortMon de www.sysinternals.com. Cet outil est buggé et permet au port mort de traîner dans le registre si le port est fermé pendant qu'il est surveillé.

Dans ce cas, la seule solution est de redémarrer l'ordinateur.

0

Comme d'autres l'ont mentionné, il est très spécifique au pilote. Il ne semble pas y avoir un moyen de vérifier avec l'API .Net si un port renvoyé par GetPortNames() existe réellement et est valide. En ce qui concerne la raison pour laquelle les ports se comportent ainsi, j'ai constaté que certains pilotes USB vers série provoquent le blocage de l'application lorsque le port est débranché brusquement.

D'autres pilotes, souvent ceux qui ne se plantent pas, conservent le port dans la liste jusqu'à ce que votre application le ferme, puis il disparaît. Si vous tentez de lire ou d'écrire sur le port périmé, des délais d'attente ou des erreurs se produisent (généralement). Vraisemblablement, afin de ne pas planter l'application, le pilote doit garder le port périmé pendant qu'il est encore ouvert dans l'application.

Si vous rebranchez le port, certains pilotes peuvent même le reconnecter à votre application, d'autres ne reconnaîtront pas le port tant que votre application n'aura pas fermé le port périmé. Ce comportement de reconnexion peut être quelque peu dangereux si le port a disparu parce que le périphérique a redémarré, car il sera soudainement dans un état différent de ce que votre application attend sans une indication évidente qu'il a été réinitialisé. Au moins, si vous obtenez des erreurs du port, vous savez que quelque chose s'est passé.

J'ai également constaté que si j'oublie de fermer le port, il ne disparaîtra pas de la liste tant que le garbage collector ne disposera pas de l'objet SerialPort.

+0

> "Certains pilotes peuvent même être reconnectés à votre application". Je n'ai jamais vu ça. Avec quel appareil l'avez-vous observé? – Elmue