可直接复制编译,只要环境没问题,应该能编译通过

#pragma once
#include <iostream>
#include <iomanip>
#include <sstream>

// 蓝牙API需要的头文件
#include <afxtempl.h>
#include <BluetoothAPIs.h>
#include <bthdef.h>
#include <bthsdpdef.h>
#include <ws2bth.h>
#include <WinSock2.h>
#include <string>
#include <string.h>

#include <winspool.h>   // 获取串口列表所需

#pragma comment(lib,"Irprops.lib")

#define NAME_LEN 100

using namespace std;

int getLocalBluetooth(HANDLE p_local_bluetooth);
string int2hexstring(int a);
string wideChar2string(WCHAR* pWCString);
int scanRemoteBluetooth(HANDLE p_local_bluetooth, string bluetooths[], int length);
int clearAttributeBluetooth(HANDLE p_local_bluetooth, string bluetooths[], int size);
int scanComServer(string comlist[]);
string compareComList(string oldComList[100], string newComList[100]);
void Split(const string& src, const string& separator, string input[]);


// 创建数组,用来存放bdi 全局
CArray < BLUETOOTH_DEVICE_INFO, BLUETOOTH_DEVICE_INFO&> remote_bluetooth;  // 周边蓝牙设备

int main(int argc, char* argv[])
{
	string bluetooths[100];    // 蓝牙名字列表
	int size = 0;              // bluetooths 的有效长度

	// 外部输入蓝牙名字
	char** input_temp = argv;
	input_temp++;              // 不要0位置的参数
	while (*input_temp != NULL) {
		cout << *input_temp << endl;
		bluetooths[size] = *input_temp;
		size++;
		++input_temp;
	}

	cout << "有效长度size = " << size<<endl;
	


	// 1、获取本地蓝牙句柄
	HANDLE hRadio = NULL;
	int res = getLocalBluetooth(hRadio);
	if (res == -1) {
		// 获取本地蓝牙句柄失败
		cout << "return:" << res << endl;
		return -1;
	}

	// 2、清空 remote_bluetooth 列表,清空已经配对的蓝牙
	remote_bluetooth.RemoveAll();
	clearAttributeBluetooth(hRadio, bluetooths, size);

	// 3、扫描目标蓝牙
	int res2 = scanRemoteBluetooth(hRadio, bluetooths, size);
	if (res2 == -1) {
		// 未能扫描到目标蓝牙设备
		cout << "return:" << -2 << endl;
	}

	// 4、根据remote_bluetooth的数量,创建串口服务
	string oldCom[100] = {};
	string newCom[100] = {};
	for (int i = 0; i < remote_bluetooth.GetCount(); i++) {
		
		// 扫一次当前PC的串口
		scanComServer(oldCom);
		
		// 申请串口服务
		const BLUETOOTH_DEVICE_INFO *bdi = NULL;
		bdi = &remote_bluetooth[i];
		const GUID *guid = NULL;
		guid = &SerialPortServiceClass_UUID;
		BluetoothSetServiceState(hRadio, bdi, guid, BLUETOOTH_SERVICE_ENABLE);

		// 再扫描一次当前串口
		scanComServer(newCom);

		// 对比两个串口列表
		string myCom = compareComList(oldCom, newCom);

		cout << "#蓝牙:";
		wcout << bdi->szName;
		cout << "--" << myCom << endl;
	}

	return 0;
}



struct bluetooth2com
{
	string bluetoothName;  // 蓝牙名称
	string comName;        // 串口名称
};

// 获取本地蓝牙
int getLocalBluetooth(HANDLE p_local_bluetooth)
{
	BLUETOOTH_FIND_RADIO_PARAMS bfrp;   // 本地蓝牙结构体
	bfrp.dwSize = sizeof(bfrp);

	// 获取本地蓝牙操作句柄,
	HANDLE local_bluetooth = p_local_bluetooth;             // 本地蓝牙句柄 本地蓝牙在windows API中被称为 radio
	HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&bfrp, &local_bluetooth); 
	
	// 获取本地蓝牙详细信息;调用 BluetoothGetRadioInfo 函数
	BLUETOOTH_RADIO_INFO local_bluetooth_message = { sizeof(local_bluetooth_message) };     // 蓝牙信息结构体
	PBLUETOOTH_RADIO_INFO p_local_bluetooth_message = &local_bluetooth_message;
	DWORD result = BluetoothGetRadioInfo(local_bluetooth, p_local_bluetooth_message);

	if (result == ERROR_SUCCESS) {
		cout << "搜索到本地蓝牙,获取其信息..." << endl;
	}
	else {
		return -1;
	}

	// 解析本地蓝牙信息,并展示
	// 蓝牙名称
	cout << "名称:";
	wcout << local_bluetooth_message.szName << endl;

	// 蓝牙地址, 从 reBytes中获取,地址是逆序的,长度是6
	cout << "地址:";
	for (int i = 5; i >= 0; i--) {
		cout << int2hexstring((int)local_bluetooth_message.address.rgBytes[i]);
		if (i != 0) {
			cout << ":";
		}
	}
	cout << endl;

	return 0;
}

// 扫描周边的蓝牙
int scanRemoteBluetooth(HANDLE p_local_bluetooth, string bluetooths[],int length) 
{
	
	/*
		p_local_bluetooth  本地蓝牙句柄
		bluetooths         蓝牙名称 string 列表
		length             蓝牙名称列表的有效长度
	*/
	
	// 蓝牙搜索条件结构体
	BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp = { sizeof(bdsp) };
	bdsp.fReturnAuthenticated = 1;   // 返回经过身份验证的蓝牙设备
	bdsp.fReturnRemembered = 1;      // 返回记住的蓝牙设备
	bdsp.fReturnUnknown = 1;         // 返回未知的蓝牙设备
	bdsp.fReturnConnected = 1;       // 返回已连接的蓝牙设备
	bdsp.fIssueInquiry = 1;          // 发出新一轮的查询
	bdsp.cTimeoutMultiplier = 30;    // 1.28s的增量,1.28 * 20
	bdsp.hRadio = p_local_bluetooth; // 有效的本地蓝牙句柄,如果是NULL,在所有本地蓝牙无线电上进行查询

	// 蓝牙设备结构体
	BLUETOOTH_DEVICE_INFO bdi[20];
	for (int i = 0; i < 20; i++) {
		bdi[i].dwSize = sizeof(bdi[i]);
	}

	// 搜索周边第一个蓝牙设备
	HBLUETOOTH_DEVICE_FIND hdf = BluetoothFindFirstDevice(&bdsp, &bdi[0]);    // 返回的hdf 句柄留给 BluetoothFindNextDevice使用
	if (hdf == NULL) {
		cout << "获取句柄失败" << endl;
		return -1;
	}

	int count = 0;
	do {
		// 如果扫到了第一个蓝牙设备
		string bluetooth_name = wideChar2string(bdi[count].szName);
		for (int i = 0; i < length; i++) {
			if (bluetooth_name == bluetooths[i]) {
				remote_bluetooth.Add(bdi[count]);
			}
		}
		count++;
	} while (BluetoothFindNextDevice(hdf, &bdi[count]));

	// 对比 remote_bluetooth 和 bluetooths 的长度,搜索到所有目标蓝牙
	if (remote_bluetooth.GetCount() == length) {
		cout << "匹配完成" << endl;
		for (int i = 0; i < remote_bluetooth.GetCount(); i++) {
			wcout << remote_bluetooth[i].szName << endl;
		}
		return 0;
	}
	// 没有所有到所有目标蓝牙,将没有搜索到的打印出来
	else {
		// 第一层循环:遍历所有目标蓝牙的名字
		for (int i = 0; i < length; i++) {
			string temp_name = bluetooths[i];
			int sign = 0;        // 匹配到是1,没匹配到是0

			// 第二层循环:遍历匹配到的蓝牙数组
			for (int j = 0; j < remote_bluetooth.GetCount(); j++) {
				string t = wideChar2string(remote_bluetooth[j].szName);

				if (t == temp_name) {
					sign = 1;
				}
			}
			if (sign == 0) {
				cout << "未能匹配到:" << temp_name << endl;
			}
			if (sign == 1) {
				cout << "匹配到:" << temp_name << endl;
			}
		}
		return -1;
	}

	return -1;
};

// 清除已配对的蓝牙  应该只清楚要配对的蓝牙
int clearAttributeBluetooth(HANDLE p_local_bluetooth, string bluetooths[], int size)
{
	/*
	p_local_bluetooth  本地蓝牙操作句柄
	bluetooths         要配对蓝牙的名称列表
	size               bluetooths数组长度
	*/


	// 蓝牙搜索条件结构体
	BLUETOOTH_DEVICE_SEARCH_PARAMS bdsp = { sizeof(bdsp) };
	bdsp.fReturnAuthenticated = 1;   // 返回经过身份验证的蓝牙设备
	bdsp.fReturnRemembered = 1;      // 返回记住的蓝牙设备
	bdsp.fReturnUnknown = 0;         // 返回未知的蓝牙设备
	bdsp.fReturnConnected = 0;       // 返回已连接的蓝牙设备
	bdsp.fIssueInquiry = 0;          // 发出新一轮的查询
	bdsp.cTimeoutMultiplier = 0;     // 1.28s的增量,1.28 * 20
	bdsp.hRadio = p_local_bluetooth; // 有效的本地蓝牙句柄,如果是NULL,在所有本地蓝牙无线电上进行查询

	// 蓝牙设备结构体
	BLUETOOTH_DEVICE_INFO bdi[20];
	for (int i = 0; i < 20; i++) {
		bdi[i].dwSize = sizeof(bdi[i]);
	}

	// 搜索周边第一个蓝牙设备
	HBLUETOOTH_DEVICE_FIND hdf = BluetoothFindFirstDevice(&bdsp, &bdi[0]);    // 返回的hdf 句柄留给 BluetoothFindNextDevice使用
	if (hdf == NULL) {
		return -1;
	}


	int count = 0;
	do {

		// 搜索到的蓝牙名称
		string temp_name = wideChar2string(bdi[count].szName);
		const BLUETOOTH_ADDRESS *pAddres = NULL;
		
		// 遍历bluetooths
		for (int i = 0; i < size; i++) {

			// 如果当前搜索到的蓝牙名称在bluetooths中,删去该蓝牙的串口服务
			if (temp_name == bluetooths[i]) {
				pAddres = &bdi[count].Address;
				BluetoothRemoveDevice(pAddres);   // 移除改蓝牙
				cout << "移除所有服务:" << temp_name << endl;
			}
		}

		count++;
	} while (BluetoothFindNextDevice(hdf, &bdi[count]));

	

	return 0;
};

// 建立串口服务
int setComServer(HANDLE p_local_bluetooth, BLUETOOTH_DEVICE_INFO bdi,GUID guidService, DWORD flag)
{	
	// 1.扫描当前存在串口
	string comList[256];  // 串口名数组


	// 2.一个蓝牙新建一个串口服务
	// 3.再扫描当前存在串口
	// 4.对比两次扫描的串口结果,多出来的那个串口就是改蓝牙申请的串口服务
	return 0;
};


// 获取windows所有串口列表
int scanComServer(string comlist[]) {
	HKEY hKey;
	LPCTSTR data_Set = _T("HARDWARE\\DEVICEMAP\\SERIALCOMM\\");
	LONG ret0 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, &hKey);
	if (ret0 != ERROR_SUCCESS)
	{
		wcout << (L"错误:无法打开有关的hKEY");
		return -1;
	}

	DWORD dwIndex = 0;
	int count = 0;
	while (1)
	{
		LONG Status;
		CHAR Name[256] = { 0 };
		UCHAR szPortName[80] = { 0 };
		DWORD dwName;
		DWORD dwSizeofPortName;
		DWORD Type;
		dwName = sizeof(Name);
		dwSizeofPortName = sizeof(szPortName);
		Status = RegEnumValue(hKey, dwIndex++, (LPWSTR)Name, &dwName, NULL, &Type,
			szPortName, &dwSizeofPortName);

		if ((Status == ERROR_SUCCESS) || (Status == ERROR_MORE_DATA))
		{
			CString str;
			str.Format(L"%s", szPortName);
			comlist[count] = CT2A(str.GetBuffer());
			count++;
			//TRACE("\n-------%s", str);COM_SERIAL_PORT_LIST.AddString(str);    
			/*cout << comlist[count];*/
		}
		else
		{
			break;
		}
	}
	RegCloseKey(hKey);
	return 0;
};

// 将 int 转成 16进制的 string
string int2hexstring(int a) {
	stringstream ioss;
	string s_temp;
	string zero = "0";

	ioss << setiosflags(ios::uppercase) << hex << a;
	ioss >> s_temp;

	int strlength = s_temp.length();
	if (strlength == 1) {
		s_temp = zero + s_temp;
	}

	return s_temp;
}

// 将双字节的字符串转成string
string wideChar2string(WCHAR* pWCString) 
{
	// 获取传入的pWCString长度,用于开辟控件
	int pSize = WideCharToMultiByte(CP_OEMCP, 0, pWCString, wcslen(pWCString), NULL, 0, NULL, NULL);
	char* pCString = new char[pSize + 1];  // 新建 char数组

	// 调用双字节字符串装成单字节字符串
	WideCharToMultiByte(CP_OEMCP, 0, pWCString, wcslen(pWCString), pCString, pSize, NULL, NULL);
	pCString[pSize] = '\0';
	
	// 赋值给string
	string pString = pCString;

	// 释放 new 申请的空间
	delete pCString;

	return pString;
};

// 对比两个串口列表,输出新增加的那个串口
string compareComList(string oldComList[100], string newComList[100])
{	
	string defaultCom = "COM1";
	// 获取两个字符串数组的长度
	int old = 100;
	int newc = 100;


	// 第一层循环:遍历 newComList 列表
	for (int i = 0; i < newc; i++) {
		string temp_newc = newComList[i];
		int sign = 1;   // 0 旧串口  1 新增串口

		// 第二层循环:遍历 oldComList 列表
		for (int j = 0; j < old; j++) {
			string temp_old = oldComList[j];

			if (temp_newc == temp_old) {
				// 不是新增的串口
				sign = 0;
			}
		}

		if (sign == 1) {
			// 找到了新增的串口
			return temp_newc;
		}

	}
	return defaultCom;
};

// 分割字符串

void Split(const string& src, const string& separator, string input[]) //字符串分割到数组
{

	//参数1:要分割的字符串;参数2:作为分隔符的字符;参数3:存放分割后的字符串的vector向量

	string str = src;
	string substring;
	string::size_type start = 0, index;
	index = str.find_first_of(separator, start);

	int count = 0;
	do
	{
		if (index != string::npos)
		{
			substring = str.substr(start, index - start);
			input[count] = substring;
			count++;
			start = index + separator.size();
			index = str.find(separator, start);
			if (start == string::npos) break;
		}
	} while (index != string::npos);

	//the last part
	substring = str.substr(start);
	input[count] = substring;

}