检测本机所有的串并端口
#include <setupapi.h>
typedef HKEY (__stdcall SETUPDIOPENDEVREGKEY)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM);
typedef BOOL (__stdcall SETUPDICLASSGUIDSFROMNAME)(LPCTSTR, LPGUID, DWORD, PDWORD);
typedef BOOL (__stdcall SETUPDIDESTROYDEVICEINFOLIST)(HDEVINFO);
typedef BOOL (__stdcall SETUPDIENUMDEVICEINFO)(HDEVINFO, DWORD, PSP_DEVINFO_DATA);
typedef HDEVINFO (__stdcall SETUPDIGETCLASSDEVS)(LPGUID, LPCTSTR, HWND, DWORD);
typedef BOOL (__stdcall SETUPDIGETDEVICEREGISTRYPROPERTY)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD);
BOOL IsNumeric(LPCTSTR pszString, BOOL bIgnoreColon)
{
int nLen = _tcslen(pszString);
if (nLen == 0)
return FALSE;
//Assume the best
BOOL bNumeric = TRUE;
for (int i=0; i<nLen && bNumeric; i++)
{
bNumeric = (_istdigit(pszString[i]) != 0);
if (bIgnoreColon && (pszString[i] == _T(':')))
bNumeric = TRUE;
}
return bNumeric;
}
void TestPorts()
{
CString strUsbstring = "USB Serial Port";
BOOL bFound = FALSE;
HINSTANCE hSetupAPI = LoadLibrary(_T("SETUPAPI.DLL"));
if (hSetupAPI == NULL){
AfxMessageBox("加载动态连接库失败!");
return;
}
SETUPDIOPENDEVREGKEY* lpfnLPSETUPDIOPENDEVREGKEY = (SETUPDIOPENDEVREGKEY*) GetProcAddress(hSetupAPI, "SetupDiOpenDevRegKey");
#ifdef _UNICODE
SETUPDICLASSGUIDSFROMNAME* lpfnSETUPDICLASSGUIDSFROMNAME = (SETUPDICLASSGUIDSFROMNAME*) GetProcAddress(hSetupAPI, "SetupDiClassGuidsFromNameW");
SETUPDIGETCLASSDEVS* lpfnSETUPDIGETCLASSDEVS = (SETUPDIGETCLASSDEVS*) GetProcAddress(hSetupAPI, "SetupDiGetClassDevsW");
SETUPDIGETDEVICEREGISTRYPROPERTY* lpfnSETUPDIGETDEVICEREGISTRYPROPERTY = (SETUPDIGETDEVICEREGISTRYPROPERTY*) GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyW");
#else
SETUPDICLASSGUIDSFROMNAME* lpfnSETUPDICLASSGUIDSFROMNAME = (SETUPDICLASSGUIDSFROMNAME*) GetProcAddress(hSetupAPI, "SetupDiClassGuidsFromNameA");
SETUPDIGETCLASSDEVS* lpfnSETUPDIGETCLASSDEVS = (SETUPDIGETCLASSDEVS*) GetProcAddress(hSetupAPI, "SetupDiGetClassDevsA");
SETUPDIGETDEVICEREGISTRYPROPERTY* lpfnSETUPDIGETDEVICEREGISTRYPROPERTY = (SETUPDIGETDEVICEREGISTRYPROPERTY*) GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyA");
#endif
SETUPDIDESTROYDEVICEINFOLIST* lpfnSETUPDIDESTROYDEVICEINFOLIST = (SETUPDIDESTROYDEVICEINFOLIST*) GetProcAddress(hSetupAPI, "SetupDiDestroyDeviceInfoList");
SETUPDIENUMDEVICEINFO* lpfnSETUPDIENUMDEVICEINFO = (SETUPDIENUMDEVICEINFO*) GetProcAddress(hSetupAPI, "SetupDiEnumDeviceInfo");
if ((lpfnLPSETUPDIOPENDEVREGKEY == NULL) || (lpfnSETUPDICLASSGUIDSFROMNAME == NULL) || (lpfnSETUPDIDESTROYDEVICEINFOLIST == NULL) ||
(lpfnSETUPDIENUMDEVICEINFO == NULL) || (lpfnSETUPDIGETCLASSDEVS == NULL) || (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY == NULL))
{
//Unload the setup dll
FreeLibrary(hSetupAPI);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
AfxMessageBox("加载函数失败!");
return;
}
//First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName
DWORD dwGuids = 0;
lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), NULL, 0, &dwGuids);
if (dwGuids == 0)
{
//Unload the setup dll
FreeLibrary(hSetupAPI);
AfxMessageBox("第一次执行转化GUID失败!");
return;
}
//Allocate the needed memory
GUID* pGuids = new GUID[dwGuids];
//Call the function again
if (!lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), pGuids, dwGuids, &dwGuids))
{
//Free up the memory before we return
delete [] pGuids;
//Unload the setup dll
FreeLibrary(hSetupAPI);
AfxMessageBox("第二次执行转化GUID失败!");
return;
}
//Now create a "device information set" which is required to enumerate all the ports
HDEVINFO hDevInfoSet = lpfnSETUPDIGETCLASSDEVS(pGuids, NULL, NULL, DIGCF_PRESENT);
if (hDevInfoSet == INVALID_HANDLE_VALUE)
{
//Free up the memory before we return
delete [] pGuids;
//Unload the setup dll
FreeLibrary(hSetupAPI);
AfxMessageBox("取得设备信息集失败!");
return;
}
//Finished with the Guids by this time
delete [] pGuids;
pGuids = NULL;
//Finally do the enumeration
BOOL bMoreItems = TRUE;
int nIndex = 0;
SP_DEVINFO_DATA devInfo;
while (bMoreItems)
{
//Enumerate the current device
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
bMoreItems = lpfnSETUPDIENUMDEVICEINFO(hDevInfoSet, nIndex, &devInfo);
if (bMoreItems)
{
//Did we find a serial port for this device
BOOL bAdded = FALSE;
//Get the registry key which stores the ports settings
HKEY hDeviceKey = lpfnLPSETUPDIOPENDEVREGKEY(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
TCHAR pszPortName[256];
memset(pszPortName,0,sizeof(pszPortName));
if (hDeviceKey)
{
//Read in the name of the port
//TCHAR pszPortName[256];
DWORD dwSize = sizeof(pszPortName);
DWORD dwType = 0;
if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, (LPBYTE) pszPortName, &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
{
//If it looks like "COMX" then
//add it to the array which will be returned
int nLen = _tcslen(pszPortName);
if (nLen > 3)
{
if ((_tcsnicmp(pszPortName, _T("COM"), 3) == 0) && IsNumeric(&pszPortName[3], FALSE))
{
//Work out the port number
int nPort = _ttoi(&pszPortName[3]);
CString ssstr(_T("发现串口"));
CString ssstr1;
ssstr1.Format("%d",nPort);
ssstr.Append(ssstr1);
AfxMessageBox(ssstr);
//ports.Add(nPort);
bAdded = TRUE;
}else if ((_tcsnicmp(pszPortName, _T("LPT"), 3) == 0) && IsNumeric(&pszPortName[3], FALSE))
{
int nPort = _ttoi(&pszPortName[3]);
CString ssstr(_T("发现并口"));
CString ssstr1;
ssstr1.Format("%d",nPort);
ssstr.Append(ssstr1);
AfxMessageBox(ssstr);
//ports.Add(nPort);
bAdded = TRUE;
}
}
}
//Close the key now that we are finished with it
RegCloseKey(hDeviceKey);
}
//If the port was a serial port, then also try to get its friendly name
if (bAdded)
{
TCHAR pszFriendlyName[256];
DWORD dwSize = sizeof(pszFriendlyName);
DWORD dwType = 0;
if (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, (PBYTE)pszFriendlyName, dwSize, &dwSize) && (dwType == REG_SZ))
// sFriendlyNames.Add(pszFriendlyName);
// else
// sFriendlyNames.Add(_T(""));
{
//校验com口是否是usb虚拟设备
CString strName = pszFriendlyName;
if(strName.Find(strUsbstring) != -1)
{
//是usb虚拟设备
//AfxMessageBox(pszPortName);
//AfxMessageBox(strName);
CString szComName = pszPortName;
bFound = TRUE;
AfxMessageBox("这是一个USB虚拟COM口!");
AfxMessageBox(szComName);
}
}
}
AfxMessageBox(pszPortName);
}
++nIndex;
}
//Free up the "device information set" now that we are finished with it
lpfnSETUPDIDESTROYDEVICEINFOLIST(hDevInfoSet);
//Unload the setup dll
FreeLibrary(hSetupAPI);
CString sssss;
sssss.Format("共找到%d个端口",(nIndex-1));
AfxMessageBox(sssss);
}