在C++程序中开启和禁用Windows设备的无线网卡的方法
1.列出当前网卡:SetupDiEnumDeviceInfo
2.找出当前无线网卡的名字(用natviewifiapi)
3.卸载\安装此驱动
问题:
log为:SetupDiSetClassInstallParamsfailed.-536870347
完整代码如下:
//ControlWirelessCard.cpp:Definestheentrypointfortheconsoleapplication. // #include"stdafx.h" #include<windows.h> #include<SetupAPI.h> #include<devguid.h> #include<string> #include<cfgmgr32.h> #include<wlanapi.h> #pragmacomment(lib,"setupapi.lib") #pragmacomment(lib,"wlanapi.lib") usingnamespacestd; wstringgetWirelessNetworkCardName() { wstringwirelessName; HANDLEhClient=NULL; DWORDdwMaxClient=2;// DWORDdwCurVersion=0; DWORDdwResult=0; DWORDdwRetVal=0; intiRet=0; WCHARGuidString[39]={0}; unsignedinti; /*variablesusedforWlanEnumInterfaces*/ PWLAN_INTERFACE_INFO_LISTpIfList=NULL; PWLAN_INTERFACE_INFOpIfInfo=NULL; dwResult=WlanOpenHandle(dwMaxClient,NULL,&dwCurVersion,&hClient); if(dwResult!=ERROR_SUCCESS){ wprintf(L"WlanOpenHandlefailedwitherror:%u\n",dwResult); returnwirelessName; } dwResult=WlanEnumInterfaces(hClient,NULL,&pIfList); if(dwResult!=ERROR_SUCCESS){ wprintf(L"WlanEnumInterfacesfailedwitherror:%u\n",dwResult); returnwirelessName; }else{ PWLAN_AVAILABLE_NETWORK_LISTpWLAN_AVAILABLE_NETWORK_LIST=NULL; dwResult=WlanGetAvailableNetworkList(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid, WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES, NULL,&pWLAN_AVAILABLE_NETWORK_LIST); if(dwResult!=ERROR_SUCCESS) { printf("WlanGetAvailableNetworkListfailedwitherror:%u\n",dwResult); WlanFreeMemory(pWLAN_AVAILABLE_NETWORK_LIST); returnwirelessName; } for(i=0;i<(int)pIfList->dwNumberOfItems;i++){ pIfInfo=(WLAN_INTERFACE_INFO*)&pIfList->InterfaceInfo[i]; iRet=StringFromGUID2(pIfInfo->InterfaceGuid,(LPOLESTR)&GuidString, sizeof(GuidString)/sizeof(*GuidString)); wirelessName=pIfInfo->strInterfaceDescription; } } returnwirelessName; } BOOLchangeStatus(DWORDNewStatus,DWORDSelectedItem,HDEVINFOhDevInfo) { LPTSTRlpszMsg=NULL; HCURSORhCursor=NULL; try { SP_PROPCHANGE_PARAMSPropChangeParams={sizeof(SP_CLASSINSTALL_HEADER)}; SP_DEVINFO_DATADeviceInfoData={sizeof(SP_DEVINFO_DATA)}; hCursor=SetCursor(LoadCursor(NULL,IDC_WAIT)); //GetahandletotheSelectedItem. if(!SetupDiEnumDeviceInfo(hDevInfo,SelectedItem,&DeviceInfoData)) { wprintf(L"SetupDiEnumDeviceInfofailed.%d\n",GetLastError()); throwlpszMsg; } //SetthePropChangeParamsstructure. PropChangeParams.ClassInstallHeader.InstallFunction=DIF_PROPERTYCHANGE; PropChangeParams.Scope=DICS_FLAG_GLOBAL; PropChangeParams.StateChange=NewStatus; if(!SetupDiSetClassInstallParams(hDevInfo,&DeviceInfoData,(SP_CLASSINSTALL_HEADER*)&PropChangeParams, sizeof(PropChangeParams))) { wprintf(L"SetupDiSetClassInstallParamsfailed.%d\n",GetLastError()); throwlpszMsg; } //CalltheClassInstallerandperformthechange. if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,&DeviceInfoData)) { wprintf(L"SetupDiCallClassInstallerfailed.%d\n",GetLastError()); throwlpszMsg; } SetCursor(hCursor); returnTRUE; } catch(TCHAR*pszError) { SetCursor(hCursor); if(NULL!=lpszMsg) { LocalFree((HLOCAL)lpszMsg); } returnFALSE; } } int_tmain(intargc,_TCHAR*argv[]) { LPTSTRlpszMsg=NULL; try { /* TCHAR*GUIDString=NULL; GUIDguid; ZeroMemory(&guid,sizeof(GUID)); GUIDString=_T("4d36e972-e325-11ce-bfc1-08002be10318"); UuidFromString((unsignedchar*)GUIDString,&guid); */ //GUIDguid=getWirelessNetworkCardGUID(); HDEVINFOhDevInfo=SetupDiGetClassDevs(&GUID_DEVCLASS_NET,/*L"WIRELESS"*/NULL,NULL,DIGCF_PRESENT); //HDEVINFOhDevInfo=SetupDiGetClassDevs(&guid,/*L"WIRELESS"*/NULL,NULL,DIGCF_PRESENT); if(INVALID_HANDLE_VALUE==hDevInfo) { wprintf(L"INVALID_HANDLE_VALUE"); return-1; } DWORDi; intIcount=0; SP_DEVINFO_DATADeviceInfoData; ZeroMemory(&DeviceInfoData,sizeof(SP_DEVINFO_DATA)); DeviceInfoData.cbSize=sizeof(SP_DEVINFO_DATA); for(i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);++i) { //GetDeviceInfo LPTSTRbuffer=NULL; DWORDbuffersize=0; DWORDStatus,Problem; BOOLbDisabled=FALSE; while(!SetupDiGetDeviceRegistryProperty( hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,//Readthenamesofthedesignatedcard NULL, (PBYTE)buffer, buffersize, &buffersize) ) { if(GetLastError()==ERROR_INSUFFICIENT_BUFFER) { if(buffer)LocalFree(buffer); buffer=(LPTSTR)LocalAlloc(LPTR,buffersize); } else { wprintf(L"readnetworkcardfailed!"); } } std::wstringstrEthernet=buffer; //wprintf(L"thebufferis%ws\n",buffer); wstringwirelessName=getWirelessNetworkCardName(); if(wirelessName.empty()) { wprintf(L"wirelessNameISempty\n"); return-1; } //wprintf(L"wirelessNameis%ws\n",wirelessName); if(wirelessName==buffer) { wprintf(L"Foundthewirelesscard:%ws\n",wirelessName); if(inti=CM_Get_DevNode_Status(&Status,&Problem,DeviceInfoData.DevInst,0)!=CR_SUCCESS) { wprintf(L"CM_Get_DevNode_Statusfailed.%d\n",GetLastError()); throw"failed\n"; } if(!((Status&DN_HAS_PROBLEM)&&(CM_PROB_DISABLED==Problem))) { bDisabled=FALSE; } if((Status&DN_HAS_PROBLEM)&&(CM_PROB_DISABLED==Problem)) { bDisabled=TRUE; } if(bDisabled==FALSE) { wprintf(L"disablethenetworkcard\n"); changeStatus(DICS_DISABLE,i,hDevInfo);//disable } if(bDisabled==TRUE) { wprintf(L"enablethenetworkcard\n"); changeStatus(DICS_ENABLE,i,hDevInfo);//enable } } } returnSetupDiDestroyDeviceInfoList(hDevInfo); } catch(TCHAR*pszError) { if(NULL!=lpszMsg) { LocalFree((HLOCAL)lpszMsg); } returnFALSE; } return0; }
一些常见错误解决
一、
从错误返回值入手。
-536870347,用windows自带计算器,选择程序员模式,将此十进制转换为16进制为E0000235.
用此错误号搜索,就是大名鼎鼎的32位程序跑在64位系统中报错。
虽然我用的64位win8下VS编译的程序,但是编译选项中仍然是WIN32程序。那么我们只需要修改成x64编译即可,操作如下。
BUILD-->ConfigurationManager...-->找到要修改的project,将platform选择为x64.
如果没有,说明没有添加x64编译项,接着上面,在platform中选择<New...>-->Newplatform下选x64-->OK.
二、
编译64位程序,运行之。
仍然报错,返回值是5.ACCESS_DENIED.
权限不够,我们需要申请高权限。如下申请Admin权限:
你项目的Properties-->Linker-->ManifestFile-->UACExecutionLevel选requireAdministrator。
三、
继续运行。卸载无线网卡驱动成功。
但是上一篇的程序仍然有个问题,由于驱动卸载了,就不能用wlanapi得到无线网卡名称,
所以程序加载无线网卡驱动就会失败。
我们可以用关键字“WirelessNetworkAdapter”来查找无线网卡,省掉使用wlanapi那一步。