21xrx.com
2025-02-16 22:05:41 Sunday
登录
文章检索 我的文章 写文章
如何在C++中获取USB端口的名称
2023-07-04 20:24:49 深夜i     --     --
C++ USB 端口名称 获取

在现代科技中,各种设备的连接方式越来越多元化。USB (Universal Serial Bus)也因其方便、通用性和极高的可扩展性,成为了主流连接方式之一。但是,在使用USB连接设备时,我们有时需要知道USB端口的名称,这对于接口选择和调试都非常有帮助。

在C++中,我们可以通过Windows API来获取USB端口的名称。具体的实现方法如下:

首先,我们需要引入WinUSB.h头文件来使用Windows API中的相关函数。接着,我们需要使用SetupAPI库来枚举已连接的USB设备。在获取到USB设备后,我们还需要使用Ungaze函数来关闭设备句柄,避免资源泄露。

以下是具体的代码实现:


#include <windows.h>

#include <winusb.h>

#include <SetupAPI.h>

#include <Cfgmgr32.h>

#include <iostream>

using namespace std;

#define MAX_DEVICE_ID_LEN 200

// 获取USB端口的名称

wstring GetUSBPortName(GUID classGuid)

{

  HDEVINFO deviceInfoSet = SetupDiGetClassDevs(&classGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

  DWORD deviceIndex = 0;

  SP_DEVICE_INTERFACE_DATA deviceInterfaceData;

  deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

  

  // 枚举所有已连接的USB设备

  while (SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &classGuid, deviceIndex, &deviceInterfaceData))

  {

    DWORD requiredSize = 0;

    // 获取设备接口的详细信息

    SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, NULL, 0, &requiredSize, NULL);

    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(requiredSize);

    deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    

    if (SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, deviceInterfaceDetailData, requiredSize, &requiredSize, NULL))

    {

      HANDLE deviceHandle = CreateFile(deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

      if (deviceHandle != INVALID_HANDLE_VALUE)

      {

        UCHAR stringDescriptor[256];

        stringDescriptor[0] = 0;

        // 通过USB设备的描述符来获取USB端口名称

        if (WinUsb_GetDescriptor(deviceHandle, USB_DEVICE_DESCRIPTOR_TYPE, 0, 0, stringDescriptor, sizeof(stringDescriptor), NULL))

        {

          wstring usbPortName;

          UNICODE_STRING unicodeString;

          // 将USB端口名称从UTF-8格式转化为Unicode格式

          RtlInitAnsiString(&unicodeString, (PCHAR)stringDescriptor + 14);

          RtlAnsiStringToUnicodeString(&unicodeString, &unicodeString, TRUE);

          usbPortName = unicodeString.Buffer;

          RtlFreeUnicodeString(&unicodeString);

          CloseHandle(deviceHandle);

          free(deviceInterfaceDetailData);

          SetupDiDestroyDeviceInfoList(deviceInfoSet);

          return usbPortName;

        }

        CloseHandle(deviceHandle);

      }

    }

    free(deviceInterfaceDetailData);

    deviceIndex++;

  }

  SetupDiDestroyDeviceInfoList(deviceInfoSet);

  return L"";

}

int main()

{

  GUID classGuid;

  wchar_t deviceClassGUIDString[] = L"{36FC9E60-C465-11CF-8056-444553540000}"; // USB设备类GUID

  HRESULT hr = CLSIDFromString(deviceClassGUIDString, &classGuid);

  if (FAILED(hr))

  

    wcout << "获取USB设备类GUID失败" << endl;

    return 0;

  

  wstring portName = GetUSBPortName(classGuid);

  if (!portName.empty())

  

    wcout << "USB端口名称:" << portName << endl;

  

  else

  

    wcout << "未找到USB设备" << endl;

  

  return 0;

}

在上面的代码示例中,我们首先定义了GUID结构体来表示USB设备的类GUID。然后,通过调用SetupDiGetClassDevs()函数来获取已连接的USB设备列表。在枚举到USB设备后,我们调用SetupDiGetDeviceInterfaceDetail()函数来获取设备接口的详细信息,并通过CreateFile()函数打开设备句柄。接下来,我们使用WinUsb_GetDescriptor()函数获取设备描述符,并从中获取USB端口名称。

通过上述方法,我们可以轻松地获取USB端口名称,从而在实际的调试过程中能够更好地进行接口选择和调试。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复
    相似文章