admin 管理员组

文章数量: 1087139


2024年12月24日发(作者:postman干嘛的)

不重起Windows直接更改IP地址的三种方法

有很多网友都遇到过更改IP地址但是要重启机器的问题,在这里,为大家

介绍几种不重启Windows直接更改IP地址的方法。首先是调用

DhcpNotifyConfigChange的方法,后面还有修改注册表跟使用“iphlpapi”的方

法。

一、未公开函数:DhcpNotifyConfigChange

设置IP地址只需要更改注册表中关于适配器的相应设置,但更改后需要重

新启动系统才能生效,而AddIPAddress函数只能添加IP而不是更改当前的IP,

我们在Windows NT/2000界面上操作不需要重新启动就可以生效,那系统到底

做了什么额外的工作才使IP设置直接生效呢?笔者通过跟踪中API

的调用发现在中调用了中一个未公开的API函数

DhcpNotifyConfigChange,现将不重新启动WINDOWS直接更改IP地址的详细

方法介绍如下:

1、获取适配器名称

这里指的适配器名称要区别于适配器描述,比如我的一块网卡,适配器描述

是:Realtek RTL8139(A) PCI Fast Ethernet Adapter,适配器名称为:

{66156DC3-44A4-434C-B8A9-0E5DB4B3EEAD}。获取适配器名称的方法有多

种:

1.1 调用IP helper API取得适配器名称 ULONG ulAdapterInfoSize =

sizeof(IP_ADAPTER_INFO);

IP_ADAPTER_INFO *pAdapterInfoBkp, *pAdapterInfo =

(IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];

if(GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) ==

ERROR_BUFFER_OVERFLOW ) // 缓冲区不够大

{

delete pAdapterInfo;

pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];

pAdapterInfoBkp = pAdapterInfo;

}

if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) ==

ERROR_SUCCESS )

{

do{ // 遍历所有适配器

if(pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET) // 判断是否为以太网

接口

{

// pAdapterInfo->Description 是适配器描述

// pAdapterInfo->AdapterName 是适配器名称

}

pAdapterInfo = pAdapterInfo->Next;

}while(pAdapterInfo);

}

delete pAdapterInfoBkp;

1.2 读取注册表取得适配器名称

在Windows2000中可以通过遍历

HKEY_LOCAL_MACHINESystemCurrentControlSetControlClass{4d36e972-e3

25-11ce-bfc1-08002be10318}000n (n是从0开始编号的数字)所有接口,在

Windows NT中可以读取

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows

NTCurrentVersionNetworkCards中的信息,下面以Windows2000为例:

HKEY hKey, hSubKey, hNdiIntKey;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

"SystemCurrentControlSetControlClass{4d36e972-e325-11ce-bfc1-08002b

e10318}",

0,

KEY_READ,

&hKey) != ERROR_SUCCESS)

return FALSE; DWORD dwIndex = 0;

DWORD dwBufSize = 256;

DWORD dwDataType;

char szSubKey[256];

unsigned

{

char szData[256]; while(RegEnumKeyEx(hKey, dwIndex++,

szSubKey, &dwBufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)

if(RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) ==

ERROR_SUCCESS)

{

if(RegOpenKeyEx(hSubKey, "NdiInterfaces", 0, KEY_READ, &hNdiIntKey)

== ERROR_SUCCESS)

{

dwBufSize = 256;

if(RegQueryValueEx(hNdiIntKey, "LowerRange", 0, &dwDataType, szData,

&dwBufSize) == ERROR_SUCCESS)

{

if(strcmp((char*)szData, "ethernet") == 0) // 判断是不是以太网卡

{

dwBufSize = 256;

if(RegQueryValueEx(hSubKey, "DriverDesc", 0, &dwDataType, szData,

&dwBufSize) == ERROR_SUCCESS)

{

// szData 中便是适配器详细描述

dwBufSize = 256;

if(RegQueryValueEx(hSubKey, "NetCfgInstanceID", 0, &dwDataType, szData,

&dwBufSize) == ERROR_SUCCESS)

{

// szData 中便是适配器名称

}

}

}

}

RegCloseKey(hNdiIntKey);

}

RegCloseKey(hSubKey);

} dwBufSize = 256;

} /* end of while */ RegCloseKey(hKey);

2、将IP信息写入注册表

代码如下:

BOOL RegSetIP(LPCTSTR lpszAdapterName, LPCTSTR pIPAddress,

LPCTSTR pNetMask, LPCTSTR pNetGate)

{

HKEY hKey;

string

strKeyName += lpszAdapterName;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

strKeyName.c_str(),

0,

KEY_WRITE,

&hKey) != ERROR_SUCCESS)

return FALSE; char mszIPAddress[100];

char mszNetMask[100];

char mszNetGate[100]; strncpy(mszIPAddress, pIPAddress, 98);

strncpy(mszNetMask, pNetMask, 98);

strncpy(mszNetGate, pNetGate, 98); int nIP, nMask, nGate; nIP =

strlen(mszIPAddress);

nMask = strlen(mszNetMask);

nGate = strlen(mszNetGate); *(mszIPAddress + nIP + 1) = 0x00; //

REG_MULTI_SZ数据需要在后面再加个0

nIP += 2; *(mszNetMask + nMask + 1) = 0x00;

nMask += 2; *(mszNetGate + nGate + 1) = 0x00;

nGate += 2; RegSetValueEx(hKey, "IPAddress", 0, REG_MULTI_SZ, (unsigned

char*)mszIPAddress, nIP);

RegSetValueEx(hKey,

RegSetValueEx(hKey,

}

"SubnetMask",

"DefaultGateway",

0,

0,

REG_MULTI_SZ,

REG_MULTI_SZ,

(unsigned

(unsigned

char*)mszNetMask, nMask);

char*)mszNetGate, nGate); RegCloseKey(hKey); return TRUE;

strKeyName =

"SYSTEMCurrentControlSetServicesTcpipParametersInterfaces";

3、调用DhcpNotifyConfigChange通知配置的改变

未公开函数DhcpNotifyConfigChange位于 中,原型如下:

BOOL DhcpNotifyConfigChange(

LPWSTR lpwszServerName, // 本地机器为NULL

LPWSTR lpwszAdapterName, // 适配器名称

BOOL bNewIpAddress, // TRUE表示更改IP

DWORD dwIpIndex, // 指明第几个IP地址,如果只有该接口只有一个IP地址则

为0

DWORD dwIpAddress, // IP地址

DWORD dwSubNetMask, // 子网掩码

int nDhcpAction ); // 对DHCP的操作 0:不修改, 1:启用 DHCP,2:禁用 DHCP

具体调用代码如下:

BOOL NotifyIPChange(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR

pIPAddress, LPCTSTR pNetMask)

{

BOOL bResult = FALSE;

HINSTANCE hDhcpDll;

DHCPNOTIFYPROC pDhcpNotifyProc;

WCHAR wcAdapterName[256];

-1,

FALSE;

MultiByteToWideChar(CP_ACP,

if((hDhcpDll

0,

=

=

lpszAdapterName,

return

NULL)

if((pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, nIndex,

inet_addr(pIPAddress), inet_addr(pNetMask), 0) == ERROR_SUCCESS)

bResult = TRUE; FreeLibrary(hDhcpDll);

return bResult;

}

二、修改注册表:网卡重启

更改Windows网卡属性选项中IP地址, 通过对比前后注册表, 可以发现以下几

处发生变化

wcAdapterName,256);

LoadLibrary("dhcpcsvc")) == NULL)

if((pDhcpNotifyProc

(DHCPNOTIFYPROC)GetProcAddress(hDhcpDll, "DhcpNotifyConfigChange")) !=

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices

TcpipParametersInterfaces{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}]

"IPAddress"

"SubnetMask"

"DefaultGateway"

"NameServer"

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices{97EFDAD8-E

B2D-4F40-9B07-0FCD706FCB6D}ParametersTcpip]

"IPAddress"

"SubnetMask"

"DefaultGateway"

[HKEY_LOCAL_MACHINESYSTEMControlSet001ServicesTcpipParametersIn

terfaces{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}]

"IPAddress"

"SubnetMask"

"DefaultGateway"

"NameServer"

[HKEY_LOCAL_MACHINESYSTEMControlSet001Services{97EFDAD8-EB2D

-4F40-9B07-0FCD706FCB6D}ParametersTcpip]

"IPAddress"

"SubnetMask"

"DefaultGateway"

其中{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}是网卡名称

(AdapterName),不同的网卡,不同的接入位置,不同的接入的时间,对应的值

都不一样, 它的值是第一次接入系统时,由系统生成的GUID值。此处

CurrentControlSet实际是ControlSet001的别名。

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices

TcpipParametersInterfaces{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}

]

"IPAddress"

"SubnetMask"

"DefaultGateway"

"NameServer"

是主要的设置处。

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices{97EFDA

D8-EB2D-4F40-9B07-0FCD706FCB6D}ParametersTcpip]

"IPAddress"

"SubnetMask"

"DefaultGateway"

对一些服务有影响,如不设置,用netstat可以看到原来的IP地址仍处于监

听状态(?)。

但为了使设置生效,还有很重要的一步,即重启网卡。更改网卡的配置,一

般而言需要重启网卡,如Linux系统,只需运行

#ifconfig eth0 down

#ifconfig eht0 up

就可以实现网卡的重启。Windows环境下的步骤与之类似:先禁用本地连接

(网卡),再启用本地连接(网卡)。但没有相应的命令或者直接的API。所幸的是

DDK提供一套设备安装函数,用于控制系统设备,包括控制设备的状态改变。(点

击查看详细代码附件)

总结:通过网卡重启更改IP的方法有两个步骤:修改注册表,重启网卡。

重启网卡的全过程上面已作描述。注册表修改的内容为文中列出四个主要项,如

{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}的网卡名称即是内部设备名,在

adapter结构中已给出。整个注册表修改的过程比较简单,本文不加叙述。

三、使用“iphlpapi”一卡多IP

除以上两个方法外,笔者再介绍一种方法。无论是在Windows下还是在Linux

下,一块网卡都可同时具有多个IP地址。根据TCP/IP原理,在网络层标识通信

节点是IP地址,在链路层上的则是MAC地址。只要通过ARP,将多个IP与一

个MAC对应起来,就可实现一网卡多IP(其实是一MAC多IP)。系统本身也有

相应的设置选项,如windows是通过TCP/IP属性的高级选项添加的,Linux下

可由ifconfig命令添加。iphlpapi提供AddIPAddress和DelIPAddress。如果能先

加入新的IP,再去除原来的IP,即可实现IP地址的更改。

不重起Windows直接更改IP地址

作者:浙江省温岭电信局 王骏

注:本文适用于WINDOWS NT/2000/XP/2003

下载本文示例工程

源代码运行效果图如下:

设置IP地址只需要更改注册表中关于适配器的相应设置,但更改后需要重

新启动系统才能生效,而AddIPAddress函数只能添加IP而不是更改当前的IP,

我们在Windows NT/2000界面上操作不需要重新启动就可以生效,那系统到底

做了什么额外的工作才使IP设置直接生效呢?笔者通过跟踪中API

的调用发现在中调用了中一个未公开的

API:DhcpNotifyConfigChange,现将不重新启动WINDOWS直接更改IP地址的

详细方法介绍如下:

一、获取适配器名称

这里指的适配器名称要区别于适配器描述,比如我的一块网卡,适配器描述是:

Realtek RTL8139(A) PCI Fast Ethernet Adapter,适配器名称为:

{66156DC3-44A4-434C-B8A9-0E5DB4B3EEAD}。获取适配器名称的方法有多

种:

1.1 调用IP helper API取得适配器名称

ULONG ulAdapterInfoSize = sizeof(IP_ADAPTER_INFO);

IP_ADAPTER_INFO

if(

*pAdapterInfoBkp, *pAdapterInfo

&ulAdapterInfoSize)

=

==

(IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];

GetAdaptersInfo(pAdapterInfo,

ERROR_BUFFER_OVERFLOW ) // 缓冲区不够大

{

}

if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_SUCCESS )

{

do{ // 遍历所有适配器

if(pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET) // 判断是否为

delete pAdapterInfo;

pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];

pAdapterInfoBkp = pAdapterInfo;

以太网接口

}

delete pAdapterInfoBkp;

1.2 读取注册表取得适配器名称

在Windows2000中可以通过遍历

{

}

pAdapterInfo = pAdapterInfo->Next;

// pAdapterInfo->Description 是适配器描述

// pAdapterInfo->AdapterName 是适配器名称

}while(pAdapterInfo);

HKEY_LOCAL_MACHINESystemCurrentControlSetControlClass{4d36e972-e3

25-11ce-bfc1-08002be10318}000n (n是从0开始编号的数字)所有接口, 在

Windows NT中可以读取

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows

NTCurrentVersionNetworkCards中的信息,下面以Windows2000为例:

HKEY hKey, hSubKey, hNdiIntKey;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

DWORD dwIndex = 0;

DWORD dwBufSize = 256;

DWORD dwDataType;

char szSubKey[256];

unsigned char szData[256];

while(RegEnumKeyEx(hKey, dwIndex++, szSubKey, &dwBufSize, NULL, NULL,

NULL, NULL) == ERROR_SUCCESS)

{

if(RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) ==

{

"NdiInterfaces", 0, KEY_READ,

ERROR_SUCCESS)

if(RegOpenKeyEx(hSubKey,

{

dwBufSize = 256;

if(RegQueryValueEx(hNdiIntKey, "LowerRange", 0, &dwDataType,

{

if(strcmp((char*)szData, "ethernet") == 0) // 判断是不是以

"SystemCurrentControlSetControlClass{4d36e972-e325-11ce-bfc1-08002b

0,

KEY_READ,

&hKey) != ERROR_SUCCESS)

e10318}",

return FALSE;

&hNdiIntKey) == ERROR_SUCCESS)

szData, &dwBufSize) == ERROR_SUCCESS)

太网卡

{

dwBufSize = 256;

if(RegQueryValueEx(hSubKey, "DriverDesc", 0, &dwDataType,

szData, &dwBufSize) == ERROR_SUCCESS)

}

dwBufSize = 256;

/* end of while */

}

}

RegCloseKey(hSubKey);

}

RegCloseKey(hNdiIntKey);

}

{

}

// szData 中便是适配器详细描述

dwBufSize = 256;

if(RegQueryValueEx(hSubKey, "NetCfgInstanceID", 0,

{

}

// szData 中便是适配器名称

&dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)

RegCloseKey(hKey);

二、将IP信息写入注册表

代码如下:

BOOL RegSetIP(LPCTSTR lpszAdapterName, LPCTSTR pIPAddress, LPCTSTR

pNetMask, LPCTSTR pNetGate)

{

HKEY hKey;

string

strKeyName += lpszAdapterName;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

strKeyName.c_str(),

strKeyName =

"SYSTEMCurrentControlSetServicesTcpipParametersInterfaces";

0,

KEY_WRITE,

&hKey) != ERROR_SUCCESS)

return FALSE;

char mszIPAddress[100];

char mszNetMask[100];

char mszNetGate[100];

strncpy(mszIPAddress, pIPAddress, 98);

strncpy(mszNetMask, pNetMask, 98);

strncpy(mszNetGate, pNetGate, 98);

int nIP, nMask, nGate;

nIP = strlen(mszIPAddress);

nMask = strlen(mszNetMask);

nGate = strlen(mszNetGate);

*(mszIPAddress + nIP + 1) = 0x00; // REG_MULTI_SZ数据需要在后面再

加个0

*(mszNetGate + nGate + 1) = 0x00;

nGate += 2;

RegSetValueEx(hKey,

RegSetValueEx(hKey,

"IPAddress",

"SubnetMask",

0,

0,

REG_MULTI_SZ,

REG_MULTI_SZ,

(unsigned

(unsigned

*(mszNetMask + nMask + 1) = 0x00;

nMask += 2;

nIP += 2;

char*)mszIPAddress, nIP);

char*)mszNetMask, nMask);

}

RegSetValueEx(hKey, "DefaultGateway", 0, REG_MULTI_SZ, (unsigned

char*)mszNetGate, nGate);

RegCloseKey(hKey);

return TRUE;

三、调用DhcpNotifyConfigChange通知配置的改变

未公开函数DhcpNotifyConfigChange位于 中,原型如下:

BOOL DhcpNotifyConfigChange(

LPWSTR lpwszServerName, // 本地机器为NULL

LPWSTR lpwszAdapterName, // 适配器名称

BOOL bNewIpAddress, // TRUE表示更改IP

DWORD dwIpIndex, // 指明第几个IP地址,如果只有该接口只有一个IP地

址则为0

DWORD dwIpAddress, // IP地址

DWORD dwSubNetMask, // 子网掩码

int nDhcpAction ); // 对DHCP的操作 0:不修改, 1:启用 DHCP,2:禁用

DHCP

具体调用代码如下:

BOOL NotifyIPChange(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR

pIPAddress, LPCTSTR pNetMask)

{

BOOL bResult = FALSE;

hDhcpDll;

pDhcpNotifyProc;

HINSTANCE

DHCPNOTIFYPROC

WCHAR wcAdapterName[256];

MultiByteToWideChar(CP_ACP, 0, lpszAdapterName, -1, wcAdapterName,256);

}

if((hDhcpDll = LoadLibrary("dhcpcsvc")) == NULL)

return FALSE;

= (DHCPNOTIFYPROC)GetProcAddress(hDhcpDll,

wcAdapterName, TRUE, nIndex,

if((pDhcpNotifyProc

"DhcpNotifyConfigChange")) != NULL)

if((pDhcpNotifyProc)(NULL,

bResult = TRUE;

inet_addr(pIPAddress), inet_addr(pNetMask), 0) == ERROR_SUCCESS)

FreeLibrary(hDhcpDll);

return bResult;

请教:VC中如何动态更改网卡IP地址(不重启系统) 问题点数:0、回复次数:20Top

1 楼liugy(不知道的太多)回复于 2003-08-01 17:28:05 得分 0

先建立一个批处理文件

内容如下:

netsh

interface

ip

set address "本地连接" static 192.168.0.2 255.255.255.0 192.168.0.1

exit

VC中:winexe("");

试一下看看Top

2 楼liugy(不知道的太多)回复于 2003-08-01 18:26:08 得分 0

更改一下:

1 c:根目录下建立

内容如下:

interface

ip

set address "本地连接" static 192.168.0.2 255.255.255.0 192.168.0.1

exit

2 c:根目录下建立

内容如下:

netsh <

3 VC中:

WinExec("c:", SW_HIDE);

即可。VC6下测试通过。

说明一下:

set address "本地连接" static 192.168.0.2 255.255.255.0 192.168.0.1

"本地连接"就是网络邻居的属性里边的那个名字

192.168.0.2 设定的IP

255.255.255.0 掩码

192.168.0.1 网关

如果改为:add address "本地连接

" static 192.168.0.2 255.255.255.0 192.168.0.1

变成添加一个IP

Top

3 楼dutzhp(void)回复于 2003-08-01 18:43:36 得分 0

UpTop

4 楼wos(tbye)回复于 2003-08-01 19:01:11 得分 0

可以吗?在windows2000下应该可以,在win98下好像就要重启哦:)

Top

5 楼apcad(新手上路)回复于 2003-08-01 20:45:49 得分 0

good!

学到一些东西!!

借楼主位谢谢liugy(光哥) !!!Top

6 楼ysdesigned(清泉)回复于 2003-08-01 20:57:19 得分 0

win98 也可以不重器

修改后(可通过修改注册表来修改)

必须先禁用后启动网卡

/Expert/topic/1941/?temp=.317959Top

7 楼canoe_eyes(阿里)回复于 2003-08-01 21:13:09 得分 0

win98 使用

HKEY AppPathKey = NULL;

LONG lRet =RegOpenKeyEx( HKEY_LOCAL_MACHINE,"SYSTEMCurrentControl

SetServices"+NetAdapt+"ParametersTcpip",0,KEY_EXECUTE|KEY_READ|KEY_ALL_A

CCESS,&AppPathKey);

DWORD dwSize = MAXPATH;

unsigned char szAppPath[MAXPATH];

if(RegQueryValueEx(AppPathKey,"IpAddress",NULL,NULL,szAppPath,&dwSize)!= ERRO

R_SUCCESS )

{

AfxMessageBox("Error while Accessing registry");

return;

}Top

8 楼wzswgbx(我总是问个不休)回复于 2003-08-01 23:14:26 得分 0

好象这些都不是楼主要的吧,我想他是要在编程里实现

不知iphlpapi行不行?Top

9 楼lemonasia(哪吒)回复于 2003-08-02 00:59:26 得分 0

IP helper API 就是干这个的Top

10 楼jian_yan(一知半解)回复于 2003-08-02 01:35:45 得分 0

有两个函数允许你增添或删除特定适配器的IP地址,它们是: AddIpAddress和

DeleteIpAddress IP助手函数。使用这两个函数时,需要知道网络适配器的索引编号和IP

场景编号。自己查MSDN吧。Top

11 楼linfeng1216(这件事很难)回复于 2003-10-17 23:02:58 得分 0

AddIpAddress()可以,我试过了,但那是临时的,重启后自动消失.Top

12 楼wujinpinga(滴水穿石)回复于 2003-10-18 06:40:33 得分 0

//-----------------------------------------------------------------

// 取得所有网卡信息

//-----------------------------------------------------------------

BOOL GetAdapterInfo()

{

// 这里的代码适合WINDOWS2000,对于NT需要读取

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionNetworkCa

rds

HKEY hKey, hSubKey, hNdiIntKey;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

"SystemCurrentControlSetControlClass{4d36e972-e325-11ce-bfc1-08002be10318}",

0,

KEY_READ,

&hKey) != ERROR_SUCCESS)

return FALSE;

DWORD dwIndex = 0;

DWORD dwBufSize = 256;

DWORD dwDataType;

char szSubKey[256];

unsigned char szData[256];

while(RegEnumKeyEx(hKey, dwIndex++, szSubKey, &dwBufSize, NULL, NULL,

NULL, NULL) == ERROR_SUCCESS)

{

//AfxMessageBox(szSubKey);

if(RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) == ERROR_S

UCCESS)

{

if(RegOpenKeyEx(hSubKey, "NdiInterfaces", 0, KEY_READ, &hNdiIntKey) ==

ERROR_SUCCESS)

{

dwBufSize = 256;

if(RegQueryValueEx(hNdiIntKey, "LowerRange", 0, &dwDataType, szData, &dwB

ufSize) == ERROR_SUCCESS)

{

if(strcmp((char*)szData, "ethernet") == 0) // 判断是不是以太网卡

{

dwBufSize = 256;

if(RegQueryValueEx(hSubKey, "DriverDesc", 0, &dwDataType, szData, &dwBufSi

ze) == ERROR_SUCCESS)

{

ADAPTER_INFO *pAI = new ADAPTER_INFO;

pAI->strDriverDesc = (LPCTSTR)szData;

//AfxMessageBox((LPCTSTR)szData);

dwBufSize = 256;

if(RegQueryValueEx(hSubKey, "NetCfgInstanceID", 0, &dwDataType, szData, &d

wBufSize) == ERROR_SUCCESS)

{

pAI->strName = (LPCTSTR)szData;

//AfxMessageBox((LPCTSTR)szData);

RegGetIP(pAI, (LPCTSTR)szData);

//AfxMessageBox((LPCTSTR)szData);

}

_back(pAI); // 加入到容器中

}

}

}

RegCloseKey(hNdiIntKey);

}

RegCloseKey(hSubKey);

}

dwBufSize = 256;

} /* end of while */

RegCloseKey(hKey);

/*

// 可以使用GetAdaptersInfo来取得网卡信息,但其显示的名称不是很具体

ULONG ulAdapterInfoSize = sizeof(IP_ADAPTER_INFO);

IP_ADAPTER_INFO *pAdapterInfoBkp, *pAdapterInfo = (IP_ADAPTER_INFO*)n

ew char[ulAdapterInfoSize];

if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_BUFFER_OVE

RFLOW ) // 缓冲区不够大

{

delete pAdapterInfo;

pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];

pAdapterInfoBkp = pAdapterInfo;

}

if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_SUCCESS )

{

do {

if (pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET)

{

ADAPTER_INFO *pAI = new ADAPTER_INFO;

pAI->strDriverDesc = pAdapterInfo->Description;

pAI->strName = pAdapterInfo->AdapterName;

RegGetIP(pAI, (LPCTSTR)pAdapterInfo->AdapterName); // 因为IP_ADAPTER_INFO

中未包含掩码信息,所以干脆直接读注册表

_back(pAI);

}

pAdapterInfo = pAdapterInfo->Next;

} while(pAdapterInfo);

}

delete pAdapterInfoBkp;

*/

return TRUE;

}

//-----------------------------------------------------------------

// 得到注册表中的IP信息

// nIndex暂时未处理

//-----------------------------------------------------------------

BOOL RegGetIP(ADAPTER_INFO *pAI, LPCTSTR lpszAdapterName, int nIn

dex/* =0 */)

{

ASSERT(pAI);

HKEY hKey;

string strKeyName = "SYSTEMCurrentControlSetServicesTcpipParametersInterf

aces";

strKeyName += lpszAdapterName;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

strKeyName.c_str(),

0,

KEY_READ,

&hKey) != ERROR_SUCCESS)

return FALSE;

unsigned char szData[256];

DWORD dwDataType, dwBufSize;

dwBufSize = 256;

if(RegQueryValueEx(hKey, "IPAddress", 0, &dwDataType, szData, &dwBufSize)

== ERROR_SUCCESS)

pAI->strIP = (LPCTSTR)szData;

dwBufSize = 256;

if(RegQueryValueEx(hKey, "SubnetMask", 0, &dwDataType, szData, &dwBufSize

) == ERROR_SUCCESS)

pAI->strNetMask = (LPCTSTR)szData;

dwBufSize = 256;

if(RegQueryValueEx(hKey, "DefaultGateway", 0, &dwDataType, szData, &dwBuf

Size) == ERROR_SUCCESS)

pAI->strNetGate = (LPCTSTR)szData;

RegCloseKey(hKey);

return TRUE;

}

//-----------------------------------------------------------------

// 设置注册表中的IP信息

//-----------------------------------------------------------------

BOOL RegSetIP(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddres

s, LPCTSTR pNetMask, LPCTSTR pNetGate)

{

HKEY hKey;

string strKeyName = "SYSTEMCurrentControlSetServicesTcpipParametersInterf

aces";

strKeyName += lpszAdapterName;

if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

strKeyName.c_str(),

0,

KEY_WRITE,

&hKey) != ERROR_SUCCESS)

return FALSE;

char mszIPAddress[100];

char mszNetMask[100];

char mszNetGate[100];

strncpy(mszIPAddress, pIPAddress, 98);

strncpy(mszNetMask, pNetMask, 98);

strncpy(mszNetGate, pNetGate, 98);

int nIP, nMask, nGate;

nIP = strlen(mszIPAddress);

nMask = strlen(mszNetMask);

nGate = strlen(mszNetGate);

*(mszIPAddress + nIP + 1) = 0x00;

nIP += 2;

*(mszNetMask + nMask + 1) = 0x00;

nMask += 2;

*(mszNetGate + nGate + 1) = 0x00;

nGate += 2;

RegSetValueEx(hKey, "IPAddress", 0, REG_MULTI_SZ, (unsigned char*)mszIPAd

dress, nIP);

RegSetValueEx(hKey, "SubnetMask", 0, REG_MULTI_SZ, (unsigned char*)mszNe

tMask, nMask);

RegSetValueEx(hKey, "DefaultGateway", 0, REG_MULTI_SZ, (unsigned char*)ms

zNetGate, nGate);

RegCloseKey(hKey);

return TRUE;

}

//-----------------------------------------------------------------

// 通知IP地址的改变

//-----------------------------------------------------------------

BOOL NotifyIPChange(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIP

Address, LPCTSTR pNetMask)

{

BOOL bResult = FALSE;

HINSTANCE hDhcpDll;

DHCPNOTIFYPROC pDhcpNotifyProc;

WCHAR wcAdapterName[256];

MultiByteToWideChar(CP_ACP, 0, lpszAdapterName, -1, wcAdapterName,256);

if((hDhcpDll = LoadLibrary("dhcpcsvc")) == NULL)

return FALSE;

if((pDhcpNotifyProc = (DHCPNOTIFYPROC)GetProcAddress(hDhcpDll, "DhcpNotify

ConfigChange")) != NULL)

if((pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, nIndex, inet_addr(pIPAddress

), inet_addr(pNetMask), 0) == ERROR_SUCCESS)

bResult = TRUE;

FreeLibrary(hDhcpDll);

return bResult;

}

//-----------------------------------------------------------------

// 设置IP地址

// 如果只绑定一个IP,nIndex = 0,暂时未处理一个网卡绑定多个地址

//-----------------------------------------------------------------

BOOL SetIP(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress,

LPCTSTR pNetMask, LPCTSTR pNetGate)

{

if(!RegSetIP(lpszAdapterName, nIndex, pIPAddress, pNetMask, pNetGate))

return FALSE;

if(!NotifyIPChange(lpszAdapterName, nIndex, pIPAddress, pNetMask))

return FALSE;

return TRUE;

}Top

13 楼wujinpinga(滴水穿石)回复于 2003-10-18 06:45:14 得分 0

上面代码是截取实现这个功能的源代码中核心的几个函数,主要过程是获得网卡,IP信息

通过注册表,然后通知系统修改发生(NotifyIPChange).Top

14 楼fanfyj(鸬鹚.NET)回复于 2003-10-18 10:44:28 得分 0

upTop

15 楼bsk(bsk)回复于 2003-10-23 18:18:24 得分 0

不错不错,回去试试。

先回家Top

16 楼bsk(bsk)回复于 2003-10-24 09:46:42 得分 0

怎么我试了都不行呀?

提示:

指定了无效的接口 本地连接。Top

17 楼bsk(bsk)回复于 2003-10-24 09:47:34 得分 0

Win2000 Server下Administrator用户登陆Top

18 楼BraveHeart2222(勇敢的心2222)回复于 2003-10-25 13:12:06 得分 0

学习!1Top

19 楼yintongshun(左岸思雨)回复于 2003-10-25 13:59:59 得分 0

说个本质的问题,所谓重新启动就是把网卡的数据重新设置一下,他要先禁用在设置完数据

后再使用,那你可以先禁用网卡更改数据后再使用就可以了Top

20 楼nicolas2001(nick)回复于 2003-10-25 16:01:31 得分 0

gz

管用?

试试!


本文标签: 网卡 适配器 更改