Поиск последовательных портов USB из приложения .NET под Windows 7 - PullRequest
5 голосов
/ 17 февраля 2010

У меня есть приложение, которое ищет определенный последовательный порт FTDI с настроенными дескрипторами USB. Мой текущий код использует пример из Code Project , который ищет таблицу WMI MSSerial_PortName в root\WMI и извлекает дополнительную информацию USB из root\CIMV2\WIN32_PnPEntity.

Это хорошо работало под XP, но приложение также должно работать под обычным пользователем на Windows 7. В этой среде доступ root\WMI приводит к «Отказано в доступе» ManagementException.

Кто-нибудь может предложить способ сопоставить имя устройства DOS последовательного порта с информацией USB при работе в качестве обычного пользователя? До сих пор я просматривал таблицы root\CIMV2\WIN32_SerialPort*, но они содержат только порты материнской платы. Я также подумал об использовании SetupAPI, но я не нашел для этого полного и работающего шаблона PInvoke.

Ответы [ 2 ]

6 голосов
/ 08 октября 2010

Я нашел ответ, подходящий для нашего случая, но не общий. Все наши USB-конвертеры являются FTDI, а FTDI предоставляет DLL, которая обрабатывает эту Мой код с использованием DLL ниже:

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 голосов
/ 07 июля 2012

Это выглядит многообещающе.

С сайта FDTI можно скачать приложение «Переназначить утилиту COMNo». Это приложение показывает на всех платформах Windows, какое устройство FTDI доступно. Очень помогает проверить, какие устройства FDTI доступны.

Когда я попытался использовать ваш код в своих собственных приложениях, я обнаружил, что у меня возникли некоторые проблемы с его запуском. Если возможно, расширьте свой код, чтобы любой мог использовать его в качестве примера проекта без каких-либо усилий, чтобы сначала его скомпилировать.

Но все же большой вклад. Спасибо.

Ниже приведен пример кода, который работал для меня.

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; }
    }

}
...