kehuadong

十万个为什么 [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

 

posted on 2024-08-05 16:58  kehuadong  阅读(2)  评论(0编辑  收藏  举报

导航