verfügbare COM-Ports erkennen



  • hallo zusammen!

    ich bin nun schon seit längerem auf der suche nach einer möglichkeit programmiererisch die am pc verfügbaren (nicht nur die vorhandenen) com-ports zu erkennen. gibt es hierzu eine möglichkeit das betriebssystem zu fragen?

    bisher habe ich das so gelöst:

    int CSerial::IsAvailable(int port)
    {  
      CString strPort("");
      HANDLE  hPort = NULL;
      int nSize(0), nPort(0);
      DWORD dwErr(0);
    
      // test the port for availability
      strPort.Format("\\\\.\\COM%d", port);
      hPort = CreateFile (strPort,        // Pointer to the name of the port
                          GENERIC_READ | GENERIC_WRITE,
                                          // Access (read-write) mode
                          0,              // Share mode
                          NULL,           // Pointer to the security attribute
                          OPEN_EXISTING,  // How to open the serial port
                          0,              // Port attributes
                          NULL);          // Handle to port with attribute to copy
    
      if (hPort == INVALID_HANDLE_VALUE)  // Invalid Porthandle, port NOT available
      {
        dwErr = GetLastError();
        if (dwErr == ERROR_ACCESS_DENIED || dwErr == ERROR_GEN_FAILURE)
          return 0;   // Port exists but not available
        else
          return -1;  //Port not exists
      }
      else // Valid PortHandle
      {
        CloseHandle(hPort); // Port release
        return 1;  // Port exists
      }
    
    }
    

    diese methode rufe ich nun in einer for-schleife quasi x-mal auf und prüfe auf rückgabe 1 (denn, anzeige nur wenn verfügbar). das ist nicht die eleganteste lösung, deshalb bin ich auf der suche nach einer besseren methode.

    über die suche und auch in den faq habe ich leider nichts in diese richtung entdeckt, auch google konnte mir nicht helfen. (entweder hat sich noch niemand mit dem problem befasst, oder es ist zu einfach und un-erwähnenswert 😃 )

    freue mich auf eure antworten.

    viele Grüße
    Daniel





  • hm, da wird das ja eigentlich ähnlich gemacht. aber ich finde den teil nicht der tatsächlich vom betriebssystem die installierten ports prüft. kann mir das jemand zeigen?

    danke schon mal
    gruß
    daniel



  • DanielusITF schrieb:

    hm, da wird das ja eigentlich ähnlich gemacht. aber ich finde den teil nicht der tatsächlich vom betriebssystem die installierten ports prüft.

    guck dir den code mal genau an. der zeigt dir 4 verschiedene methoden wie man's machen kann...



  • hm, nr. 1:

    //Up to 255 COM ports are supported so we iterate through all of them seeing
      //if we can get the default configuration
      for (UINT i=1; i<256; i++)
      {
        //Form the Raw device name
        CString sPort;
        sPort.Format(_T("COM%d"), i);
    
        COMMCONFIG cc;
        DWORD dwSize = sizeof(COMMCONFIG);
        if (GetDefaultCommConfig(sPort, &cc, &dwSize))
          ports.Add(i);
      }
    

    und nr. 2:

    //Did we find a serial port for this device
          BOOL bAdded = FALSE;
    
          //Get the registry key which stores the ports settings
          HKEY hDeviceKey = lpfnLPSETUPDIOPENDEVREGKEY(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
          if (hDeviceKey)
          {
            //Read in the name of the port
            TCHAR pszPortName[256];
            DWORD dwSize = sizeof(pszPortName);
            DWORD dwType = 0;
      	    if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>(pszPortName), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
            {
              //If it looks like "COMX" then
              //add it to the array which will be returned
              size_t nLen = _tcslen(pszPortName);
              if (nLen > 3)
              {
                if ((_tcsnicmp(pszPortName, _T("COM"), 3) == 0) && IsNumeric(&pszPortName[3], FALSE))
                {
                  //Work out the port number
                  int nPort = _ttoi(&pszPortName[3]);
                  ports.Add(nPort);
    
                  bAdded = TRUE;
                }
              }
            }
    
            //Close the key now that we are finished with it
            RegCloseKey(hDeviceKey);
    

    nr 1 hab ich ja so ähnlich, mal sehen ob ich nr. 2 zum laufen kriege... aber wo nr.3 und nr.4 sind keine ahnung.

    jedenfalls vielen dank für den link
    gruß
    Daniel



  • jup, funktioniert. Dankesehr

    gruß
    Daniel


Anmelden zum Antworten