最近项目中碰到了一点问题,就是5G模组,在上电拨号成功后,在运行过程中,可能因为基站信号差,导致掉线。而且,掉线后,就再也拨不上去了。即使将5G模组设置成RNDIS模式,也无法解决这个问题。模组厂商的建议是在掉线后,将模组重置一下,简单的操作就是先“禁用”,再“启用”。具体的解决办法有两种:
1. 通过power shell来实现
禁用:
disable-netadapter -name "5G" -confirm:$false
加上-confirm:$false,就是类似于linux中rm -f *中的-f,不需要输入“yes”。“5G”即使网卡的名字
启用:
enable-netadapter -name "5G"
所以如果网卡名字不变,那么通过power shell去操作也是很简单。运行脚本的程序需要有管理员权限。
2. 通过windows API去操作
这种方法适用于那种,每次重新上电后,网卡名字可能会变化的那种情况。
BOOL DisableNetInterface(bool bStatus)
{
//string HardwareId;
HardwareId = "USB\\VID_2DEE&PID_4D38&REV_0414&MI_00";//设备的硬件ID,具体情况具体分析
DWORD NewState;
if (bStatus)
{
NewState = DICS_DISABLE;//禁用
}
else
{
NewState = DICS_ENABLE;//启用
}
DWORD i, err;
BOOL Found = false;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA spDevInfoData;
//访问系统的硬件库
hDevInfo = SetupDiGetClassDevs(NULL, "USB", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);//“USB”是设备类型,具体情况具体分析。比如有的设备是PCI类型,那么就要修改
if (hDevInfo == INVALID_HANDLE_VALUE)
{
printf("访问系统硬件出错!");
meigLog("access the system hardware fail");
return false;
}
//枚举硬件,获得需要的接口
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++)
{
DWORD DataT;
LPTSTR p, buffer = NULL;
DWORD buffersize = 1024;
buffer = (char*)LocalAlloc(LPTR, buffersize);//先预分配一部分缓存,免得后面操作的时候,报错ERROR_INSUFFICIENT_BUFFER
//获得硬件的属性值
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&spDevInfoData,
SPDRP_HARDWAREID,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
//不存在HardwareID. Continue.
meigLog("SetupDiGetDeviceRegistryProperty fail to get the hardwareId");
break;
}
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
//缓存不够大
//cout << "needed bufferSize is " << buffersize<< endl;
meigLog("SetupDiGetDeviceRegistryProperty and the buf is insufficient");
if (buffer)
LocalFree(buffer);
buffer = (char*)LocalAlloc(LPTR, buffersize);
Sleep(1000);
}
else
{
//未知错误
meigLog("SetupDiGetDeviceRegistryProperty meet unkown error");
goto cleanup_DeviceInfo;
}
}
if (GetLastError() == ERROR_INVALID_DATA)
continue;
//比较,找到和网卡ID相同的项
for (p = buffer; *p && (p<&buffer[buffersize]); p += lstrlen(p) + sizeof(TCHAR))
{
if (!_tcscmp(HardwareId.c_str(), p))
{
//找到匹配的设备
Found = TRUE;
meigLog("net card founded");
break;//我的设备只存在一个5G网卡,因此一旦找到,马上退出.
}
}
if (buffer)
LocalFree(buffer);
//如果相等
if (Found)
{
//更新设备状态
SP_PROPCHANGE_PARAMS spPropChangeParams;
spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
spPropChangeParams.Scope = DICS_FLAG_GLOBAL;
spPropChangeParams.StateChange = NewState;
if (!SetupDiSetClassInstallParams(hDevInfo, &spDevInfoData, (SP_CLASSINSTALL_HEADER*)&spPropChangeParams, sizeof(spPropChangeParams)))
{
DWORD errorcode = GetLastError();
string errlog = "SetupDiSetClassInstallParams fail,error code is " + to_string(errorcode);
meigLog(errlog);
}
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &spDevInfoData))
{
DWORD errorcode = GetLastError();
string errlog = "SetupDiCallClassInstaller fail,error code is " + to_string(errorcode);
meigLog(errlog);
}
else
{
meigLog("change device state sucess");
break;
}
}
}
cleanup_DeviceInfo:
err = GetLastError();
SetupDiDestroyDeviceInfoList(hDevInfo);
SetLastError(err);
return true;
}
如果使用这种方式,需要注意的是,如果机器是64位的,那么程序需要编译成64位。如果32位的程序,在64位机器上跑,会报错0xe0000235。