2010-02-17 3 views
5

J'ai une application qui recherche un port série FTDI spécifique avec des descripteurs USB personnalisés. Mon code actuel utilise the example from Code Project, qui recherche la table WMI MSSerial_PortName sous root\WMI et extrait les informations USB supplémentaires à partir de root\CIMV2\WIN32_PnPEntity.Recherche de ports série USB à partir d'une application .NET sous Windows 7

Cela a bien fonctionné sous XP, mais l'application doit également fonctionner sous un utilisateur standard sur Windows 7. Dans cet environnement, l'accès de root\WMI entraîne un "Accès refusé" ManagementException.

Quelqu'un peut-il suggérer un moyen de faire une référence croisée entre le nom de périphérique DOS d'un port série et les informations USB, tout en s'exécutant en tant qu'utilisateur standard? Jusqu'à présent, j'ai regardé les tables root\CIMV2\WIN32_SerialPort*, mais elles ne contiennent que des ports de carte mère. J'ai également envisagé d'utiliser SetupAPI, mais je n'ai pas trouvé de modèle PInvoke complet et fonctionnel pour cela.

Répondre

6

J'ai découvert une réponse adaptée à notre cas, mais pas générique. Nos convertisseurs USB sont tous FTDI, et FTDI fournissent un DLL that handles this. Mon code utilisant la DLL est ci-dessous:

UInt32 count = 0; 
FTDI.FT_STATUS status = ftdi.GetNumberOfDevices(ref count); 
if (status != FTDI.FT_STATUS.FT_OK) 
{ 
    log.Warn("Unable to access FTDI"); 
    return ports; 
} 
FTDI.FT_DEVICE_INFO_NODE[] list = new FTDI.FT_DEVICE_INFO_NODE[count]; 
status = ftdi.GetDeviceList(list); 
if (status != FTDI.FT_STATUS.FT_OK) 
{ 
    log.Warn("Unable to access FTDI"); 
    return ports; 
} 
foreach (FTDI.FT_DEVICE_INFO_NODE node in list) 
{ 
    if ((status = ftdi.OpenByLocation(node.LocId)) == FTDI.FT_STATUS.FT_OK) 
    { 
     try 
     { 
      string comport; 
      ftdi.GetCOMPort(out comport); 
      ports.Add(new Port(comport, node.Description, node.SerialNumber)); 
     } 
     finally 
     { 
      ftdi.Close(); 
     } 
    } 
} 
3

Cela semble prometteur. A partir du site FDTI, vous pouvez télécharger l'application "Réassigner l'utilitaire COMNo". Cette application affiche sur toutes les plates-formes Windows quel périphérique FTDI est disponible. Cela aide beaucoup de vérifier quels périphériques FDTI sont disponibles.

Lorsque j'ai essayé d'utiliser votre code dans mes propres applications, j'ai découvert que j'avais des problèmes avec la mise en marche. Si possible, étendez votre code afin que tout le monde puisse l'utiliser comme un exemple de projet sans aucun effort pour le compiler en premier.

Mais toujours une grande contribution. Merci.

Ci-dessous l'exemple de code qui a fonctionné pour moi.

using FTD2XX_NET; 
private List<FDTIPort> FindFdtiUsbDevices() 
    { 
    /////////////////////// 
    // Requires 
    // FTD2XX_NET.dll 
    /////////////////////// 

    List<FDTIPort> ports = new List<FDTIPort>(); 

    FTDI _ftdi = new FTDI(); 

    UInt32 count = 0; 
    FTDI.FT_STATUS status = _ftdi.GetNumberOfDevices(ref count); 
    if (status != FTDI.FT_STATUS.FT_OK) 
    { 
     Console.WriteLine("log.Warn: Unable to access FTDI"); 
     return ports; 
    } 

    FTDI.FT_DEVICE_INFO_NODE[] list = new FTDI.FT_DEVICE_INFO_NODE[count]; 
    status = _ftdi.GetDeviceList(list); 
    if (status != FTDI.FT_STATUS.FT_OK) 
    { 
     Console.WriteLine("log.Warn: Unable to access FTDI"); 
     return ports; 
    } 


    foreach (FTDI.FT_DEVICE_INFO_NODE node in list) 
    { 
     if ((status = _ftdi.OpenByLocation(node.LocId)) == FTDI.FT_STATUS.FT_OK) 
     { 
      try 
      { 
       string comport; 
       _ftdi.GetCOMPort(out comport); 

       if (comport != null && comport.Length > 0) 
       { 
        ports.Add(new FDTIPort(comport, node.Description.ToString(), node.SerialNumber.ToString())); 
       } 
      } 
      finally 
      { 
       _ftdi.Close(); 
      } 
     } 
    } 

    _ftdi.Dispose(); 
    return ports; 
} 

public class FDTIPort 
{ 
    private string _nodeComportName = ""; 
    private string _nodeDescription = ""; 
    private string _nodeSerialNumber = ""; 

    // Constructor 
    public FDTIPort() 
    { 
     _nodeComportName = ""; 
     _nodeDescription = ""; 
     _nodeSerialNumber = ""; 
    } 
    // Constructor 

    public FDTIPort (string nodeComportName, string nodeDescription, string nodeSerialNumber) 
    { 
     _nodeComportName = nodeComportName; 
     _nodeDescription = nodeDescription; 
     _nodeSerialNumber = nodeSerialNumber; 
    } 

    public string nodeComportName { 
     get { return this._nodeComportName; } 
    } 

    public string nodeDescription 
    { 
     get { return this._nodeDescription; } 
    } 

    public string nodeSerialNumber 
    { 
     get { return this._nodeSerialNumber; } 
    } 

} 
+0

Si quelqu'un a des problèmes, c'est parce que son FTDI n'est pas FDTI. – RW4

Questions connexes