• 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。

  • 相关阅读:
    Linux多线程环境下信号处理机制
    scp/sftp/curl/sh
    自动驾驶仿真模型搭建
    【Web】https 与 http 的区别
    合肥先进光源束测专用网络的规划-续
    Day26:内部类的详解
    张雪英部分论文集
    在UE4.27下打包VR程序并部署到PICO 3
    Python可变长关键字参数,传入时使用变量值而不是变量名作为键
    Linux CentOS 8(用户管理)
  • 原文地址:https://blog.csdn.net/guolisong/article/details/126832240