十万个为什么 [Windows] 获取串口号
#include <Windows.h>
#include <SetupAPI.h> // -lsetupapi
#include <devguid.h> // -luuid
#include <stdint.h>
#include <stdio.h>
#include <map>
#include <set>
using namespace std;
// ---------------------------------------------------------------------------
map<string, string> get_serial_ports()
{
map<string, string> port_name_to_dev_name;
HDEVINFO h_dev_info = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, NULL, NULL, DIGCF_PRESENT);
if (h_dev_info == INVALID_HANDLE_VALUE)
{
return port_name_to_dev_name;
}
SP_DEVINFO_DATA dev_info_data;
dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(h_dev_info, i, &dev_info_data); i++)
{
HKEY h_key_dev = SetupDiOpenDevRegKey(h_dev_info, &dev_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
DWORD type;
DWORD size = 256; // size会被RegQueryValueEx修改
char port_name[256];
char dev_name[256];
if (h_key_dev != INVALID_HANDLE_VALUE
&& RegQueryValueEx(h_key_dev, "PortName", NULL, &type, (LPBYTE)port_name, &size) == ERROR_SUCCESS
&& type == REG_SZ
&& SetupDiGetDeviceRegistryProperty(h_dev_info, &dev_info_data, SPDRP_DEVICEDESC, NULL, (PBYTE)dev_name, sizeof(dev_name), NULL))
{
port_name_to_dev_name[port_name] = dev_name;
}
if (h_key_dev != INVALID_HANDLE_VALUE)
{
RegCloseKey(h_key_dev);
}
}
SetupDiDestroyDeviceInfoList(h_dev_info);
return port_name_to_dev_name;
}
// ---------------------------------------------------------------------------
static set<uint32_t> get_port_id_set(const map<string, string>& port_name_to_dev_name)
{
set<uint32_t> ret;
for (const auto& kv : port_name_to_dev_name)
{
uint32_t id;
if (sscanf(kv.first.c_str(), "COM%d", &id))
{
ret.insert(id);
}
}
return ret;
}
int main()
{
for (uint32_t id : get_port_id_set(get_serial_ports()))
{
printf("id = %d\n", id);
}
}
// g++ -m32 get_serial_ports.cpp -lsetupapi -luuid