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
管用?
试试!
版权声明:本文标题:(vc源程序)不重起Windows直接更改IP地址的三种方法 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1735137495a1638961.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论