最新需要写一个程序,程序需要用到修改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);