我在程序开发过程中用到了USB转串口线,但是它虚拟成COM口后端口自动侦测就成了一个问题。在有的笔记本上它被虚拟成了COM17,如果我用程序循环从COM1到COM20,这也太慢了也太蠢了。请问哪位高手可以赐教,用WindowsAPI或者其他一些方式获取Windows的USB转串口所形成的虚拟COM口号!

解决方案 »

  1.   

    你的计算机不可能有1-20个串口,你就读注册表,注册表中的串口一个一个的真测,不会太多的。下面是读注册表串口信息的代码 HKEY hKey;
    LONG ret;
    OSVERSIONINFO  osvi;
    BOOL bOsVersionInfoEx;
    char keyinfo[100],comm_name[40],ValueName[40];
    int i;
    DWORD sType,Reserved,cbData,cbValueName; hIcon=AfxGetApp()->LoadIcon(IDI_HARDWARE);
    SetIcon(hIcon,false); ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
        osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    memset(keyinfo,0,100);
    strcpy(keyinfo,"HARDWARE\\DEVICEMAP\\SERIALCOMM");
        i=0; sType=REG_SZ;Reserved=0;
    bOsVersionInfoEx =GetVersionEx(&osvi);
        ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,keyinfo,0,KEY_ALL_ACCESS,&hKey);
    if (ret==ERROR_SUCCESS){
    // 10-25
       if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) 
       {
       for(i=1;i<=128;i++)
       {    
          sprintf(comm_name,"COM%d",i);
      if (CommPortIsUsed(comm_name)==1) m_comlist.AddString(comm_name);
       }
       }
           else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
       {
        do 
      {
        cbData=40;cbValueName=40;
        memset(comm_name,0,40); 
        memset(ValueName,0,40);
        ret=RegEnumValue(hKey,i,ValueName,&cbValueName,NULL,&sType,(LPBYTE)comm_name,&cbData);
                if (ret==ERROR_SUCCESS)
    {
                   if (CommPortIsUsed(comm_name)==1) m_comlist.AddString(comm_name);
       i++;
    }
      }while (ret==ERROR_SUCCESS);
       }
    }

    RegCloseKey(hKey);
      

  2.   

    //这是我写的用来读可用串口的函数,记得“uses Registry”,cobComName为TComboBox控件
    //读取可用串口
    function getComNames():TStringList;
    var
      reg:TRegistry;
      strName:TStringList;
      i:integer;
    begin
      strName:=TStringList.Create;
      reg:= TRegistry.Create;
      reg.RootKey:=HKEY_LOCAL_MACHINE;
      if reg.OpenKeyReadOnly('hardware\devicemap\serialcomm') then
      begin
        reg.GetValueNames(strName);
      end;
      Result:=TStringList.Create;
      for i:=0 to strName.Count-1 do
        Result.Add(reg.ReadString(strName.Strings[i]));
      reg.CloseKey;
      reg.Destroy;
    end;
    //添充到
    procedure TFcomPara.FormCreate(Sender: TObject);
    var Reg: TRegistry;
      strName:TStringList;
      i:integer;
    begin
      strName:=getComNames();
      cobComName.Clear;
      for i:=0 to strName.Count-1 do
        cobComName.AddItem(strName[i],self);
      cobComName.ItemIndex:=0;
    end;