重新设置本地网卡的配置信息,可以达到在不重启机器的情况下么,比较便捷的对当前的网络设置进行转换。
采用的方法主要有三种,一种是采用windows的netsh命令行;第二种种则是使用iphlpapi库提供的相关API来完成工作;第三种的核心操作则是采用一个
未公开的接口DhcpNotifyConfigChange来完成修改。
方法一:使用netsh系列命令
如果使用netsh的命令帮助,实际上可以看到它具备对很多计算机网络方面的信息设置功能,这里主要关注它对网卡,也就是interface操作的操作
netsh interface ip set address
为了简单起见,就直接将其参数的详细设置方法从cmd直接导出,在此记录。
用法: set address [name=]<string>
[[source=]dhcp |
[source=] static [addr=]IP address [mask=]IP subnet mask]
[[gateway=]<IP address>|none [gwmetric=]integer]
参数:
标记 值
name - 接口名称。
source - 下列值之一:
dhcp: 对于指定接口,设置用 DHCP 配置 IP
地址。
static: 设置使用本地静态配置设置 IP
地址。
gateway - 下列值之一:
<IP address>: 您设置的 IP 地址的指定默认
网关。
none: 不设置默认网关。
gwmetric - 默认网关的跃点数。如果网关设置为 'none',则
不应设置此字段。
只有在 'source' 为 'static' 时才设置下列选项:
addr - 指定接口的 IP 地址。
mask - 指定 IP 地址的子网掩码。
注释 : 用来将 IP 地址配置模式从 DHCP 模式改为 static,或从 static
模式改为 DHCP。用静态 IP 地址在接口上添加 IP 地址,或添加
默认网关。
示例 :
set address name="Local Area Connection" source=dhcp
set address local static 10.0.0.9 255.0.0.0 10.0.0.1 1
方法二:使用iphlpapi库的相关接口
思路其实很简单,就是修改主机的路由表。网关等信息其实就是本机的一个路由信息,所以可以调用
接口GetIpForwardTable来进行操作。
该接口的声明如下:
DWORD GetIpForwardTable(
__out PMIB_IPFORWARDTABLE pIpForwardTable,
__inout PULONG pdwSize,
__in BOOL bOrder
);
获取路由表信息之后,就可以针对table里需要修改的选项进行定位修改,同样修改的API也是该库来提供
DWORD SetIpForwardEntry(
__in PMIB_IPFORWARDROW pRoute
);
具体的实现代码可以参考MSDN。
方法三:使用接口DhcpNotifyConfigChange
这个方法是采用了http://www.vckbase.com/index.php/wv/645 这个页面的作者提供的方法。在这个页面上也有
十分详细的介绍,在这里为了完整性,简单的描述一下思路。
原作者发现这个方法的思路是:通过跟踪explorer.exe中API的调用发现在netcfgx.dll中调用了dhcpcsvc.dll中的
一个未公开的API DhcpNotifyConfigChange
这个接口的函数声明如下:
BOOL
DhcpNotifyConfigChange(
2.
LPWSTR
lpwszServerName,
// 本地机器为NULL
3.
LPWSTR
lpwszAdapterName,
// 适配器名称
4.
BOOL
bNewIpAddress,
// TRUE表示更改IP
5.
DWORD
dwIpIndex,
// 指明第几个IP地址,如果只有该接口只有一个IP地址则为0
6.
DWORD
dwIpAddress,
// IP地址
7.
DWORD
dwSubNetMask,
// 子网掩码
8.
int
nDhcpAction );
// 对DHCP的操作 0:不修改, 1:启用 DHCP,2:禁用 DHCP
执行步骤如下:
1.首先要获取适配器的名称。有两种方法获取,一种是采用iphlpapi.lib库里的GetAdaptersInfo接口;第二种方法是通过注册表来查找。
2.修改注册表里,该接口指示下需要修改的网络配置信息。
设置键值的接口当然是司空见惯的RegSetValueEx了,而需要修改的对应键值则位于如下指示:
"SYSTEM\\CurrentControlSet\\Services\\
Tcpip\\Parameters\\Interfaces\\";
接口来讲注册表里修改的信息“同步”到实际的网卡配置中去,达到修改的目的。
这里就直接贴上原作者的核心代码:
BOOL
NotifyIPChange(
LPCTSTR
lpszAdapterName,
int
nIndex,
LPCTSTR
pIPAddress,
LPCTSTR
pNetMask)
02.
{
03.
BOOL
bResult = FALSE;
04.
HINSTANCE
hDhcpDll;
05.
DHCPNOTIFYPROC pDhcpNotifyProc;
06.
WCHAR
wcAdapterName[256];
07.
08.
MultiByteToWideChar(CP_ACP, 0, lpszAdapterName, -1, wcAdapterName,256);
09.
10.
if
((hDhcpDll = LoadLibrary(
"dhcpcsvc"
)) == NULL)
11.
return
FALSE;
12.
13.
if
((pDhcpNotifyProc = (DHCPNOTIFYPROC)GetProcAddress(hDhcpDll,
"DhcpNotifyConfigChange"
)) != NULL)
14.
if
((pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, nIndex, inet_addr(pIPAddress), inet_addr(pNetMask), 0) == ERROR_SUCCESS)
15.
bResult = TRUE;
16.
17.
FreeLibrary(hDhcpDll);
18.
return
bResult;
19.
}