我有一个应用程序,它会查找具有自定义USB描述符的特定FTDI串行端口。我当前的代码使用the example from Code Project,它会搜索MSSerial_PortName
下的root\WMI
WMI表,并从root\CIMV2\WIN32_PnPEntity
中提取额外的USB信息。
这在XP下运行良好,但应用程序也必须在Windows 7上的标准用户下运行。在此环境中,root\WMI
的访问会导致“拒绝访问”ManagementException
。
有人建议在以标准用户身份运行时,将串口的DOS设备名称交叉引用到USB信息吗?到目前为止,我已经查看了root\CIMV2\WIN32_SerialPort*
表,但它们只包含主板端口。我也考虑使用SetupAPI
,但我还没有找到一个完整且有效的PInvoke模板。
答案 0 :(得分:6)
我发现了一个适合我们案例的答案,虽然不是一般的答案。我们的USB转换器都是FTDI,FTDI提供DLL that handles this。我使用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();
}
}
}
答案 1 :(得分:3)
这看起来很有希望。
从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; }
}
}