windows下使能/关闭硬件

最近项目中碰到了一点问题,就是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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值