编程读取注册表获取串口信息(支持Vista)
在编写串口通信程序时,经常需要列举计算机上目前可用的串口。最简单的方法是通过CreateFile串口号1~256(XP系统系统下最大支持的串口号为256),查看返回值,如果返回非INVALID_HANDLE_VALUE就证明此串口号存在。此方法简单实用,因为在只有一个串口的情况也需要遍历256个串口,需CreateFile256次,效率较低,而且不能显示目前正在使用的串口号。
下面介绍通过读取注册表获取串口号与串口个数的方法。
#define MAXCOMNO 256 //最大COM号256
typedef struct{
char name[8];
short no;
}SCOM;
/////用读注册表的方式查看系统的串口设备
void GetAvailableCom(SCOM *port,int &cnt)
{
HKEY hKey;
LONG ret;
OSVERSIONINFO osvi;
BOOL bOsVersionInfoEx;
CString keyinfo;
unsigned char comm_name[40];
char ValueName[40];
char szNO[3];
int i=0,j=0;
cnt=0;
DWORD sType,Reserved,cbData,cbValueName;
ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
keyinfo.Format(_T("HARDWARE\\DEVICEMAP\\SERIALCOMM"));
//CString keyinfo=_T("HARDWARE\\DEVICEMAP\\SERIALCOMM");
i=0; sType=REG_SZ;Reserved=0;
bOsVersionInfoEx = GetVersionEx(&osvi);
ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE,keyinfo,0,KEY_ALL_ACCESS,&hKey);
if (ret==ERROR_SUCCESS)
{
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) //WIN32,not used
{
for(i=1;i<=MAXCOMNO;i++)
{
memset(comm_name, 0, 40);
sprintf((char*)comm_name,"COM%d",i);
ret=RegEnumValue(hKey, i, ValueName, &cbValueName, NULL, &sType, comm_name, &cbData);
if(ret==ERROR_SUCCESS)
{
i++;
}
}
}
else if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) //WINNT XP 2000
{
do
{
cbData=40;cbValueName=40;
memset(comm_name,0,40);
memset(ValueName,0,40);
memset(szNO, 0, 3);
ret=RegEnumValue(hKey, i, ValueName, &cbValueName, NULL, &sType, comm_name, &cbData);
if (ret==ERROR_SUCCESS)
{
for(j=0;j<cbData;j++)
{
port->name[j]=comm_name[j];
if(j>2 && j<6)
{
szNO[j-3] = comm_name[j];
}
}
port->no = atoi(szNO);
port++;
cnt++;
i++;
}
}while(ret==ERROR_SUCCESS);
}
}
RegCloseKey(hKey);
}
port包含串口名称与编号,由于注册表中的串口名称排列并非安装串口号顺序排列而是随即排列的,便于界面中顺序列出串口号,故分别保存便于判断。cnt返回当前计算机中包含的串口数量。
注:由于在串口号大于8之后,不能直接用COM10来CreateFile,而要用\\\\.\\COM10的形式,而在COM8一下采用\\\\.\\COM1来CreateFile也是可以的。
在Vista下用此程序来读取串口号失败,其实并没有失败而是在Vista下访问注册表需要管理员权限。解决办法单击你的程序,右键属性,选择“兼容性”选项卡,勾选最下面的“请以管理员身份运行改程序”。
Recent Comments