自动识别电脑端口号代码(完整版)

14 篇文章 1 订阅

通过MFC实现:
要调用Setupapi的接口,所以
属性-》输入-》附件依赖项:添加Setupapi.lib就可以了。

#include <afxtempl.h>

// Struct used when enumerating the available serial ports
// Holds information about an individual serial port.
struct SSerInfo {
    SSerInfo() : bUsbDevice(FALSE) {}
    CString strDevPath;          // Device path for use with CreateFile()
    CString strPortName;         // Simple name (i.e. COM1)
    CString strFriendlyName;     // Full name to be displayed to a user
    BOOL bUsbDevice;             // Provided through a USB connection?
    CString strPortDesc;         // friendly name without the COMx
};

// Routine for enumerating the available serial ports. Throws a CString on
// failure, describing the error that occurred. If bIgnoreBusyPorts is TRUE,
// ports that can't be opened for read/write access are not included.
void EnumSerialPorts(CArray<SSerInfo,SSerInfo&> &asi, BOOL bIgnoreBusyPorts=TRUE);

.cpp文件实现:

// For MFC

#include "EnumSerial.h"
#include <setupapi.h>
#include <initguid.h>

// The following define is from ntddser.h in the DDK. It is also
// needed for serial port enumeration.
#ifndef GUID_CLASS_COMPORT
DEFINE_GUID(GUID_CLASS_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, \
			0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73);
#endif



void EnumSerialPorts(CArray<SSerInfo,SSerInfo&> &asi, BOOL bIgnoreBusyPorts)
{
	asi.RemoveAll();
	CString strErr;
	GUID* guidDev = (GUID*)&GUID_CLASS_COMPORT;
	HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
	SP_DEVICE_INTERFACE_DETAIL_DATA* pDetData = NULL;
	try {
		hDevInfo = SetupDiGetClassDevs(guidDev,
			NULL,
			NULL,
			DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
		if (hDevInfo == INVALID_HANDLE_VALUE)
		{
			strErr.Format(_T("SetupDiGetClassDevs failed.(err=%lx)"), GetLastError());
			throw strErr;
		}

		BOOL bOk = TRUE;
		SP_DEVICE_INTERFACE_DATA ifcData;
		DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256;
		pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)new char[dwDetDataSize];
		memset(pDetData, 0, dwDetDataSize);
		ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
		pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
		for (DWORD ii = 0; bOk; ii++)
		{
			bOk = SetupDiEnumDeviceInterfaces(hDevInfo, 
				NULL,
				guidDev,
				ii,
				&ifcData);
			if (bOk)
			{
				SP_DEVINFO_DATA devdata = { sizeof(SP_DEVINFO_DATA) };
				bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo,
					&ifcData,
					pDetData,
					dwDetDataSize,
					NULL,
					&devdata);
				if (bOk)
				{
					CString strDevPath(pDetData->DevicePath);
					TCHAR fname[256];
					TCHAR desc[256];
					BOOL bSuccess = SetupDiGetDeviceRegistryProperty(hDevInfo,
						&devdata, 
						SPDRP_FRIENDLYNAME,
						NULL,
						(PBYTE)fname,
						sizeof(fname),
						NULL);
					bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty(hDevInfo,
						&devdata,
						SPDRP_DEVICEDESC,
						NULL,
						(PBYTE)desc,
						sizeof(desc),
						NULL);

					BOOL bUsbDevice = FALSE;
					TCHAR locinfo[256];
					if (SetupDiGetDeviceRegistryProperty(hDevInfo,
						&devdata,
						SPDRP_LOCATION_INFORMATION,
						NULL,
						(PBYTE)locinfo,
						sizeof(locinfo),
						NULL))
					{
						CString tmpstr;
						tmpstr.Format(_T("%s"), locinfo);
						bUsbDevice = (lstrcmpW(tmpstr.Left(3), _T("USB")) == 0);
					}
					if (bSuccess)
					{
						SSerInfo si;
						si.strDevPath = strDevPath;
						si.strFriendlyName = fname;
						si.strPortDesc = desc;
						si.bUsbDevice = bUsbDevice;
						asi.Add(si);
					}
				}
				else
				{
					strErr.Format(_T("SetupDiGetDeviceInterfaceDetail failed.(err=%lx)"), 
						GetLastError());
					throw strErr;
				}
			}
			else
			{
				DWORD err = GetLastError();
				if (err != ERROR_NO_MORE_ITEMS)
				{
					strErr.Format(_T("SetupDiEnumDeviceInterfaces failed.(err=%lx)"), err);
					throw strErr;
				}
			}
		}
	}
	catch (CString strCatchErr)
	{
		strErr = strCatchErr;
	}
	if (pDetData != NULL)
	{
		delete[] (char*)pDetData;
	}
	if (hDevInfo != INVALID_HANDLE_VALUE)
	{
		SetupDiDestroyDeviceInfoList(hDevInfo);
	}
	if (!strErr.IsEmpty())
		throw strErr;

	for (int ii = 0; ii < asi.GetSize(); ii++)
	{
		SSerInfo& rsi = asi[ii];
		if (bIgnoreBusyPorts)
		{
			HANDLE hCom = NULL;
			hCom = CreateFile(rsi.strDevPath,
				GENERIC_READ | GENERIC_WRITE,
				0,
				NULL,
				OPEN_EXISTING,
				0,
				NULL);
			if (hCom == INVALID_HANDLE_VALUE)
			{
				asi.RemoveAt(ii);
				ii--;
				continue;
			}
			else
			{
				::CloseHandle(hCom);
			}
		}
		if (rsi.strFriendlyName.IsEmpty())
		{
			rsi.strFriendlyName = rsi.strPortName;
		}

		// If there is no description, try to make one up from
		// the friendly name.
		if (rsi.strPortDesc.IsEmpty())
		{
			// If the port name is of the form "ACME Port (COM3)"
			// then strip off the " (COM3)"
			rsi.strPortDesc = rsi.strFriendlyName;
			int startdex = rsi.strPortDesc.Find(_T("("));
			int enddex = rsi.strPortDesc.Find(_T(")"));
			if (startdex > 0 && enddex == (rsi.strPortDesc.GetLength() - 1))
			{
				rsi.strPortDesc = rsi.strPortDesc.Left(startdex);
			}
		}
			
	}

}

最后按钮实现调用:

void CMFCSerialSearchDlg::OnBnClickedEnumerateButton1()
{
	// TODO: 在此添加控件通知处理程序代码

	CArray<SSerInfo, SSerInfo&> asi;

	// Populate the list of serial ports.
	EnumSerialPorts(asi, FALSE/*include all*/);
	m_listPorts.ResetContent();
	for (int ii = 0; ii < asi.GetSize(); ii++) {
		/*if(lstrcmpW(asi[ii].strFriendlyName.Left(3), _T("USB")) == 0)*/
		m_listPorts.AddString(asi[ii].strFriendlyName);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值