最新需要写一个程序,程序需要用到修改IP部分.网上找了下资料,大部份都说直接修改注册表,然后再执行一个MS没有公开的API.
但这方法是否在WIN7下面不能工作.
然后网上有提到可以使用WMI去更改,但没有源码.自己整理了下.
第一步 需要了解WMI的相关操作. 如果你安装了VS2008的 MSDN那么可以直接访问下面的链接.
ms-help://MS.MSDNQTR.v90.en/wmisdk/wmi/example__calling_a_provider_method.htm
如果没有,那么你也可以在搜索栏输入 execquery,然后第一个就是 execquery [WMI],然后在右边栏的下面
这里也有example code的链接.了解了wmi的相关访问操作后,我们开始正式工作.
第二步 当然就是写代码,初始化wmi相关的.初始化相关代码不详述了.在msdn的example里面有.
第三步.由于很多电脑不只一个网卡,那么你要修改哪个网卡的IP地址呢.这需要指定.
怎么获取电脑上面已有网卡的信息.有人说去读注册表.这种方法有很多的不好.这里不详述.下面介绍另一种方法.
API函数 GetAdaptersAddresses,此函数能获取到当前电脑所有的网络连接的device.结果是一个链表,里面有很多项,哪一些才是我们真正的网卡呢.
PIP_ADAPTER_ADDRESSES 这个指针有个成员变量 AdapterName ,根据这个到注册表位置 HKLM\\SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\ 去找对应的名字与 AdapterName 内容一样的项.xp系统会有一个键值 MediaSubType.值为2表示 wifi 网卡 ,值为 1表示本地有线网卡.
win7系统的话,请访问键 DefaultNameResourceId 0x70E 表示wifi 网卡 0x70B表示本地有线网卡.
到现在,你已经可以知道当前电脑有多少个无线网卡,多少个本地网卡,以及他们的 ID或名字.
第四步. 从上面代码获取到的ID. 类似为 {2CAA64ED-BAA3-4473-B637-DEC65A14C8AA}
使用wmi去修改ip,因为我们要修改指定网卡的IP,所以需要一个id.
由下面代码去获取到需要修改网卡在wmi的
获取到PATH后,就需要执行wmi里面的函数. EnableStatic .这个函数的参数里字符串的数组.对于封装参数有些麻烦.
需要用到下面的代码
void stringToArrry(WCHAR *buf,VARIANT* vAriant) { BSTR strBuf = SysAllocString(buf); long strBufIndex[] = { 0 }; SAFEARRAY *ip_list = SafeArrayCreateVector(VT_BSTR, 0, 1); SafeArrayPutElement(ip_list, strBufIndex, strBuf); vAriant->vt = VT_ARRAY | VT_BSTR; vAriant->parray = ip_list; SysFreeString(strBuf); }
好了.到这,准备工作已经全部做好了.
下面贴上相关的代码.修改IP的函数
typedef struct __IP_SUBNETMASK__ { WCHAR IP[50]; WCHAR SubnetMask[50]; }IP_SUBNETMASK,*PIP_SUBNETMASK;
IP_SUBNETMASK gIpMask[2]= { {L"192.168.99.33",L"255.255.255.0"}, {L"192.168.99.66",L"255.255.255.0"}, };
void ChangeIP(PDLL_PARAMETER pDllParameter,WCHAR* ID,IP_SUBNETMASK ipMask) { _bstr_t szMethodName = L"EnableStatic"; WCHAR buf[256]; IWbemClassObject* pClass= NULL; IEnumWbemClassObject* pEnumerator = NULL; HRESULT hres ; swprintf_s(buf,sizeof(buf)/sizeof(WCHAR),L"SELECT * FROM Win32_NetworkAdapterConfiguration where SettingID = \"%s\"",ID); BSTR Sql(buf); hres = pDllParameter->Psvc->ExecQuery( bstr_t("WQL"), Sql, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator ); if(FAILED(hres)) return; IWbemClassObject *pclsObj; ULONG uReturn = 0; VARIANT gAdapterConfigPathVal; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); if(0 == uReturn) { break; } VARIANT vtProp; hr = pclsObj->Get(L"__PATH", 0, &vtProp, 0, 0); hres = pDllParameter->Psvc->GetObject(_bstr_t("Win32_NetworkAdapterConfiguration"),0,NULL,&pClass,NULL); IWbemClassObject* pInParamsDefinition = NULL; IWbemClassObject* pClassInstance = NULL; hres = pClass->GetMethod(szMethodName,0,&pInParamsDefinition,NULL); hres = pInParamsDefinition->SpawnInstance(0,&pClassInstance); stringToArrry(ipMask.IP,&gAdapterConfigPathVal); VARIANT temp; hres = pClassInstance->Put(L"IPAddress",0,&gAdapterConfigPathVal,0); hres = pClassInstance->Get(L"IPAddress",0,&temp,0,0); //WBEM_E_ACCESS_DENIED stringToArrry(ipMask.SubnetMask,&gAdapterConfigPathVal); hres = pClassInstance->Put(L"SubnetMask",0,&gAdapterConfigPathVal,0); hres = pClassInstance->Get(L"SubnetMask",0,&temp,0,0); VariantClear(&temp); IWbemClassObject* pOutClass = NULL; hres = pDllParameter->Psvc->ExecMethod(vtProp.bstrVal,szMethodName,0,NULL,pClassInstance,&pOutClass,NULL); VariantClear(&vtProp); hres = pOutClass->Get(_bstr_t(L"ReturnValue"),0,&gAdapterConfigPathVal,NULL,0); pClass->Release(); } VariantClear(&gAdapterConfigPathVal); pEnumerator->Release(); }
ChangeIP(pDllParameter,L"{2CAA64ED-BAA3-4473-B637-DEC65A14C8AA}",gIpMask[i]);
获取网卡信息的函数
char strSubkey[250]; char szSubKey[256]; DWORD keyValue; DWORD dwType =REG_DWORD; HKEY hKey; int LocalCount=0,WifiCount=0; ZeroMemory(linkList,sizeof(linkList)); OSVERSIONINFO osversioninfo = { sizeof(OSVERSIONINFO) }; GetVersionEx(&osversioninfo); PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(sizeof(IP_ADAPTER_ADDRESSES)); ULONG outBufferSize=0; if(ERROR_BUFFER_OVERFLOW == GetAdaptersAddresses(AF_INET,0,NULL,pAddresses,&outBufferSize)) { free(pAddresses); pAddresses=(PIP_ADAPTER_ADDRESSES)malloc(outBufferSize); } if(NO_ERROR == GetAdaptersAddresses(AF_INET,0,NULL,pAddresses,&outBufferSize)) { PIP_ADAPTER_ADDRESSES p=pAddresses; for (;p;) { sprintf_s(strSubkey,sizeof(strSubkey),"%s%s\\Connection",HKEY_NAME,p->AdapterName); if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, strSubkey, 0, KEY_QUERY_VALUE, &hKey )) { if(5 == osversioninfo.dwMajorVersion) { sprintf_s(szSubKey,sizeof(szSubKey),"%s","MediaSubType"); //xp os unsigned long nSize= sizeof(keyValue); if( ERROR_SUCCESS == RegQueryValueEx( hKey, szSubKey, NULL, &dwType, (byte *)&keyValue, &nSize ) ) { if(0x2 == keyValue || 0x1 == keyValue) { if(0x2 == keyValue) { WifiCount++; linkList[gLanCout].DeviceType=1;//wifi lan } else LocalCount++; sprintf_s(linkList[gLanCout].szServiceName,sizeof(linkList[gLanCout].szServiceName),"%s",p->AdapterName); UnicodeToAnsi(p->Description,linkList[gLanCout].szDescription,sizeof(linkList[gLanCout].szDescription)); //sprintf_s(linkList[gLanCout].szDescription,sizeof(linkList[gLanCout].szDescription),"%s",p->Description); gLanCout++; } } } else if(6 == osversioninfo.dwMajorVersion) { //win7 ox sprintf_s(szSubKey,sizeof(szSubKey),"%s","DefaultNameResourceId"); unsigned long nSize= sizeof(keyValue); int xy=RegQueryValueEx( hKey, szSubKey, NULL, &dwType, (byte *)&keyValue, &nSize ); if( ERROR_SUCCESS == RegQueryValueEx( hKey, szSubKey, NULL, &dwType, (byte *)&keyValue, &nSize ) ) { if(0x70E == keyValue || 0x70B == keyValue) { if(0x70E == keyValue) { WifiCount++; linkList[gLanCout].DeviceType=1; } else LocalCount++; sprintf_s(linkList[gLanCout].szServiceName,sizeof(linkList[gLanCout].szServiceName),"%s",p->AdapterName); UnicodeToAnsi(p->Description,linkList[gLanCout].szDescription,sizeof(linkList[gLanCout].szDescription)); //sprintf_s(linkList[gLanCout].szDescription,sizeof(linkList[gLanCout].szDescription),"%s",p->Description); gLanCout++; } } } RegCloseKey(hKey); } p =p->Next; } } free(pAddresses);