使用serialEnum的方法枚举设备管理器里面Ports上的com口;
实际上我有3个com口可以看到:
CFAN Newyork USB To RS232 (com6)
Prolific USB-to-Serial Comm Port (com8)
蓝牙通信端口 (com4)然而只能枚举出来两个:
Prolific USB-to-Serial Comm Port (com8)
蓝牙通信端口 (com4)希望大虾们指点一下,下面是驱动安装的inf文件以及部分的代码;(代码里面ii=2,error=0x103后退出的,没有异常的返回)我的安装stmcdc.inf文件是:

; STMicroelectronics Comunication Device Class driver instalation file
; (C)2006 Copyright STMicroelectronics
;[Version] 
Signature="$Windows NT$" 
Class=Ports
;ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} 
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%STM% 
LayoutFile=layout.inf
DriverVer=01/03/2011,2.0.9.122[Manufacturer] 
%STM%=DeviceList[DestinationDirs] 
DefaultDestDir=12 [SourceDisksFiles][SourceDisksNames][DeviceList] 
%DESCRIPTION%=STMUSB, USB\VID_0483&PID_5740 ;------------------------------------------------------------------------------
;  Windows 2000/XP Sections
;------------------------------------------------------------------------------[STMUSB.nt] 
include=mdmcpq.inf
CopyFiles=DriverCopyFiles
AddReg=STMUSB.nt.AddReg [DriverCopyFiles]
usbser.sys,,,0x20[STMUSB.nt.AddReg] 
HKR,,DevLoader,,*ntkern 
HKR,,NTMPDriver,,usbser.sys 
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" [STMUSB.nt.Services] 
AddService=usbser, 0x00000002, DriverService
[STMUSB.nt.HW]
include=mdmcpq.inf[DriverService] 
DisplayName=%DESCRIPTION% 
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys ;------------------------------------------------------------------------------
;  String Definitions
;------------------------------------------------------------------------------[Strings] 
STM="CFAN Technology"
DESCRIPTION="CFAN Newyork USB To RS232" 
我的代码是:
//long NYA10_enumserial()
extern "C" long __declspec(dllexport)  __stdcall NYA10_enumserial()
{
 CArray<SSerInfo,SSerInfo&> asi;
    CString buffer;
 unsigned long compos1,compos2;
 unsigned long com_port;
 // Populate the list of serial ports.
 EnumSerialPorts(asi,FALSE/*include all*/);
// m_listPorts.ResetContent();
 for (int ii=0; ii<asi.GetSize(); ii++) {
  //m_listPorts.AddString(asi[ii].strFriendlyName);
  if(!strcmp(asi[ii].strPortDesc,"CFAN Newyork USB To RS232"))
  //if(!strcmp(asi[ii].strPortDesc,"Prolific USB-to-Serial Comm Port"))
  {
   buffer=asi[ii].strFriendlyName;
   compos1=buffer.Find("COM");
   compos2=buffer.Find(")");
   com_port=atol(buffer.Mid(compos1+3,compos2-compos1-3));
  }
  }
 if (ii>asi.GetSize())
  return 0;
    else
  return com_port;
}
 
======
//---------------------------------------------------------------
// Routine for enumerating the available serial ports.
// Throws a CString on failure, describing the error that
// occurred. If bIgnoreBusyPorts is TRUE, ports that can't
// be opened for read/write access are not included.
 
void EnumSerialPorts(CArray<SSerInfo,SSerInfo&> &asi, BOOL bIgnoreBusyPorts)
{
 // Clear the output array
 asi.RemoveAll();
 
 // Use different techniques to enumerate the available serial
 // ports, depending on the OS we're using
 OSVERSIONINFO vi;
 vi.dwOSVersionInfoSize = sizeof(vi);
 if (!::GetVersionEx(&vi)) {
  CString str;
  str.Format("Could not get OS version. (err=%lx)",
   GetLastError());
  throw str;
 }
 // Handle windows 9x and NT4 specially
 if (vi.dwMajorVersion < 5) {
  if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT)
   EnumPortsWNt4(asi);
  else
   EnumPortsW9x(asi);
 }
 else {
  // Win2k and later support a standard API for
  // enumerating hardware devices.
  EnumPortsWdm(asi);
 }
 
 for (int ii=0; ii<asi.GetSize(); ii++)
 {
  SSerInfo& rsi = asi[ii];    
  if (bIgnoreBusyPorts) {
   // Only display ports that can be opened for read/write
   HANDLE hCom = CreateFile(rsi.strDevPath,
    GENERIC_READ | GENERIC_WRITE,
    0,    /* comm devices must be opened w/exclusive-access */
    NULL, /* no security attrs */
    OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
    0,    /* not overlapped I/O */
    NULL  /* hTemplate must be NULL for comm devices */
    );
   if (hCom == INVALID_HANDLE_VALUE) {
    // It can't be opened; remove it.
    asi.RemoveAt(ii);
    ii--;               
    continue;
   }
   else {
    // It can be opened! Close it and add it to the list
    ::CloseHandle(hCom);
   }
  }
 
  // Come up with a name for the device.
  // If there is no friendly name, use the port name.
  if (rsi.strFriendlyName.IsEmpty())
   rsi.strFriendlyName = rsi.strPortName;
 
  // If there is no description, try to make one up from
  // the friendly name.
  if (rsi.strPortDesc.IsEmpty()) {
   // If the port name is of the form "ACME Port (COM3)"
   // then strip off the " (COM3)"
   rsi.strPortDesc = rsi.strFriendlyName;
   int startdex = rsi.strPortDesc.Find(" (");
   int enddex = rsi.strPortDesc.Find(")");
   if (startdex > 0 && enddex == 
    (rsi.strPortDesc.GetLength()-1))
    rsi.strPortDesc = rsi.strPortDesc.Left(startdex);
  }
 }
}  
=====
void EnumPortsWdm(CArray<SSerInfo,SSerInfo&> &asi)
{
 CString strErr;
 // Create a device information set that will be the container for 
 // the device interfaces.
 GUID *guidDev = (GUID*) &GUID_CLASS_COMPORT;
 
 HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
 SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL;
 
 try {
  hDevInfo = SetupDiGetClassDevs( guidDev,
   NULL,
   NULL,
   DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
   );
 
  if(hDevInfo == INVALID_HANDLE_VALUE) 
  {
   strErr.Format("SetupDiGetClassDevs failed. (err=%lx)",
    GetLastError());
   throw strErr;
  }
 
  // Enumerate the serial ports
  BOOL bOk = TRUE;
  SP_DEVICE_INTERFACE_DATA ifcData;
  DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
  pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize];
  // This is required, according to the documentation. Yes,
  // it's weird.
  ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
  pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  for (DWORD ii=0; bOk; ii++) {
   bOk = SetupDiEnumDeviceInterfaces(hDevInfo,
    NULL, guidDev, ii, &ifcData);
   if (bOk) {
    // Got a device. Get the details.
    SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)};
    bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo,
     &ifcData, pDetData, dwDetDataSize, NULL, &devdata);
    if (bOk) {
     CString strDevPath(pDetData->DevicePath);
     // Got a path to the device. Try to get some more info.
     TCHAR fname[256];
     TCHAR desc[256];
     BOOL bSuccess = SetupDiGetDeviceRegistryProperty(
      hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,
      (PBYTE)fname, sizeof(fname), NULL);
     bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty(
      hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,
      (PBYTE)desc, sizeof(desc), NULL);
     BOOL bUsbDevice = FALSE;
     TCHAR locinfo[256];
     if (SetupDiGetDeviceRegistryProperty(
      hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL,
      (PBYTE)locinfo, sizeof(locinfo), NULL))
     {
      // Just check the first three characters to determine
      // if the port is connected to the USB bus. This isn't
      // an infallible method; it would be better to use the
      // BUS GUID. Currently, Windows doesn't let you query
      // that though (SPDRP_BUSTYPEGUID seems to exist in
      // documentation only).
      bUsbDevice = (strncmp(locinfo, "USB", 3)==0);
     }
     if (bSuccess) {
      // Add an entry to the array
      SSerInfo si;
      si.strDevPath = strDevPath;
      si.strFriendlyName = fname;
      si.strPortDesc = desc;
      si.bUsbDevice = bUsbDevice;
      asi.Add(si);
     }
 
    }
    else {
     strErr.Format("SetupDiGetDeviceInterfaceDetail failed. (err=%lx)",
      GetLastError());
     throw strErr;
    }
   }
   else {
    DWORD err = GetLastError();
    if (err != ERROR_NO_MORE_ITEMS) {
     strErr.Format("SetupDiEnumDeviceInterfaces failed. (err=%lx)", err);
     throw strErr;
    }
   }
  }
 }
 catch (CString strCatchErr) {
  strErr = strCatchErr;
 }
 
 if (pDetData != NULL)
  delete [] (char*)pDetData;
 if (hDevInfo != INVALID_HANDLE_VALUE)
  SetupDiDestroyDeviceInfoList(hDevInfo);
 
 if (!strErr.IsEmpty())
  throw strErr;
}
 
void EnumPortsWNt4(CArray<SSerInfo,SSerInfo&> &asi)
{
 // NT4's driver model is totally different, and not that
 // many people use NT4 anymore. Just try all the COM ports
 // between 1 and 16
 SSerInfo si;
 for (int ii=1; ii<=16; ii++) {
  CString strPort;
  strPort.Format("COM%d",ii);
  si.strDevPath = CString("\\\\.\\") + strPort;
  si.strPortName = strPort;
  asi.Add(si);
 }
}

解决方案 »

  1.   

    读注册表获取串口不行么?
    HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
      

  2.   

    在我的注册表里面有5个com,分别是com3,com4,com5,com6,com8;
    但是在设备管理里面只有3个,分别是com4,com6,com8;
    这个怎么准确的找出我需要的com6;
      

  3.   

    楼主问题高难度,看你设备里有Prolific USB-to-Serial Comm Port (com8),想请教怎么利用FTD2XX.dll开发串口通信的程序,我买了转换接头,连接笔记本上的USB口和台式机上的串口,用FTD2XX.dll提供的API函数能写数据,但不知道写到哪里(台式机上用串口调试助手看不到),楼主指点一下
      

  4.   

    原理就是根据COM口的GUID{ 0x4d36e978, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 }然后利用SetupDiGetClassDevs,SetupDiEnumDeviceInfo函数查找所有系统中的COM,枚举到CFAN Newyork USB To RS232(COM6)这个字符串,然后找到(的位置,把后面的COM6提取出来.我就是这么干的...
      

  5.   

    楼上[yjz1409267]的兄弟能否给些代码?
      

  6.   

      我现在用的是跟楼主同样的枚举代码,用的也是STMicroelectronics的这个Inf文件,设备ID跟楼主也一样,于是遇到了同样的问题。  请问楼主问题最后如何解决的?
      谢谢!