大佬教程收集整理的这篇文章主要介绍了在程序中修改IP win7 winXP(参考1),大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
https://blog.csdn.net/bbdxf/article/details/7548443@H_772_20@
以下讨论的平台依据是Window XP + SP1, 不考虑Windows其它版本的兼容性问题, 但对NT系列的系统, 理论上是通用的. @H_772_20@
方法一: 网卡重启 @H_772_20@
更改Windows网卡属性选项中IP地址, 通过对比前后注册表, 可以发现以下几处发生变化 @H_772_20@
[HKEY_LOCAL_MACHINE\SYstem\CurrentControlSet\services\Tcpip\Parameters\Interfaces\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}] @H_772_20@
"Ipaddress" @H_772_20@
"@L_481_6@mask" @H_772_20@
"DefaultGateway" @H_772_20@
"NameServer" @H_772_20@
[HKEY_LOCAL_MACHINE\SYstem\CurrentControlSet\services\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}\Parameters\Tcpip] @H_772_20@
"Ipaddress" @H_772_20@
"@L_481_6@mask" @H_772_20@
"DefaultGateway" @H_772_20@
[HKEY_LOCAL_MACHINE\SYstem\ControlSet001\services\Tcpip\Parameters\Interfaces\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}] @H_772_20@
"Ipaddress" @H_772_20@
"@L_481_6@mask" @H_772_20@
"DefaultGateway" @H_772_20@
"NameServer" @H_772_20@
[HKEY_LOCAL_MACHINE\SYstem\ControlSet001\services\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}\Parameters\Tcpip] @H_772_20@
"Ipaddress" @H_772_20@
"@L_481_6@mask" @H_772_20@
"DefaultGateway" @H_772_20@
其中{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}是网卡名称(AdapterName), 不同的网卡, 不同的接入位置, 不同的接入的时间, 对应的值都不一样, 它的值是第一次接入系统时, 由系统生成的GUID值. @H_772_20@
此处CurrentControlSet实际是ControlSet001的别名. @H_772_20@
[HKEY_LOCAL_MACHINE\SYstem\CurrentControlSet\services\Tcpip\Parameters\Interfaces\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}] @H_772_20@
"Ipaddress" @H_772_20@
"@L_481_6@mask" @H_772_20@
"DefaultGateway" @H_772_20@
"NameServer" @H_772_20@
是主要的设置处. @H_772_20@
[HKEY_LOCAL_MACHINE\SYstem\CurrentControlSet\services\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}\Parameters\Tcpip] @H_772_20@
"Ipaddress" @H_772_20@
"@L_481_6@mask" @H_772_20@
"DefaultGateway" @H_772_20@
对一些服务有影响, 如不设置, 用netstat可以看到原来的IP地址仍处于监听状态(?). @H_772_20@
但为了使设置生效, 还有很重要的一步, 即重启网卡. @H_772_20@
更改网卡的配置, 一般而言需要重启网卡, 如 @H_772_20@
Linux系统, 只需运行 @H_772_20@
#ifconfig eth0 down @H_772_20@
#ifconfig eht0 up @H_772_20@
就可以实现网卡的重启. @H_772_20@
Windows环境下的步骤与之类似: 先禁用本地连接(网卡), 再启用本地连接(网卡). 但没有相应的命令或者直接的API. 所幸的是DDK提供一套设备安装函数, 用于控制系统设备, 包括控制设备的状态改变. @H_772_20@
/**************************************************************************************** @H_772_20@
Purpose: change state of the SELEcted device @H_772_20@
Input : hDevInfo device info set @H_772_20@
pDeviceInfoData SELEcted device info @H_772_20@
NewState one of enable/disable @H_772_20@
Output : TRUE for success, falSE for Failed @H_772_20@
****************************************************************************************/ @H_772_20@
BOOL ChangeDeviceState(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDeviceInfoData, DWORD NewStatE) @H_772_20@
{ @H_772_20@
SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTall_HEADER)}; @H_772_20@
SP_DEVINSTall_PARAMS devParams; @H_772_20@
if (!pDeviceInfoData) { @H_772_20@
return falSE; @H_772_20@
} @H_772_20@
PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTall_HEADER); @H_772_20@
PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; @H_772_20@
PropChangeParams.Scope = DicS_FLAG_CONfigSPECIFIc; @H_772_20@
PropChangeParams.StateChange = NewState; @H_772_20@
PropChangeParams.HwProfile = 0; @H_772_20@
if (!SetupDiSetClassInstallParams(hDevInfo,pDeviceInfoData, @H_772_20@
(SP_CLASSINSTall_HEADER *)&PropChangeParams,sizeof(PropChangeParams)) @H_772_20@
|| !SetupDicallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,pDeviceInfoData)) { @H_772_20@
return falSE; @H_772_20@
} @H_772_20@
reutrn TRUE; @H_772_20@
} @H_772_20@
/* hDevInfo如何得到***********************************************************/ @H_772_20@
m_hDevInfo = SetupDiGetClassDevs( @H_772_20@
(LPGUID) &GUID_DEVCLASS_NET, /* GUID_DEVCLASS_NET表示仅列出网络设备 */ @H_772_20@
NULL, @H_772_20@
this->m_hWnd, @H_772_20@
DIGCF_PRESENT); @H_772_20@
if (INVALID_HANDLE_VALUE == m_hDevInfo) { @H_772_20@
return falSE; @H_772_20@
} @H_772_20@
/* pDeviceInfoData如何得到**************************************************/ @H_772_20@
k = 0; @H_772_20@
while (SetupDiEnumDeviceInfo(m_hDevInfo, k ,&deviceInfoData)) { @H_772_20@
k++; @H_772_20@
if (CR_succesS != CM_Get_DevNode_Status(&Status, &Problem, @H_772_20@
DeviceInfoData.DevInst,0)) { @H_772_20@
conTinue; @H_772_20@
} @H_772_20@
if ((Status & DN_NO_SHOW_IN_DM)) { @H_772_20@
conTinue; @H_772_20@
} @H_772_20@
if (GetRegistryProperty(m_hDevInfo, @H_772_20@
&deviceInfoData, @H_772_20@
SPDRP_FRIENDLYNAME, @H_772_20@
&pBuffer, @H_772_20@
&Length)) { @H_772_20@
m_Adapter[adapter_num].index = k - 1; /* 当前网卡在设备信息集中的索引 */ @H_772_20@
_tcscpy(m_Adapter[adapter_num].desc, pBuffer); /* 当前网卡 */ @H_772_20@
GetRegistryProperty(m_hDevInfo, @H_772_20@
&deviceInfoData, @H_772_20@
SPDRP_DRIVER, @H_772_20@
&pBuffer, @H_772_20@
&Length); @H_772_20@
_tcscpy(m_Adapter[adapter_num].driver, pBuffer); @H_772_20@
adapter_num++; @H_772_20@
} @H_772_20@
} @H_772_20@
/* GetRegistryProperty是对SetupDiGetDeviceRegistryProperty封装***************/ @H_772_20@
BOOL GetRegistryProperty(HDEVINFO DeviceInfoSet, @H_772_20@
PSP_DEVINFO_DATA DeviceInfoData, @H_772_20@
ULONG Property, @H_772_20@
LPTSTR* Buffer, @H_772_20@
PULONG Length) @H_772_20@
{ @H_772_20@
while (!SetupDiGetDeviceRegistryProperty( @H_772_20@
DeviceInfoSet, @H_772_20@
DeviceInfoData, @H_772_20@
Property, @H_772_20@
NULL, @H_772_20@
(PBYTE)(*Buffer), @H_772_20@
*Length, @H_772_20@
Length @H_772_20@
)) @H_772_20@
{ @H_772_20@
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { @H_772_20@
if (*(LPTSTR *)Buffer) @H_772_20@
LocalFree(*(LPTSTR *)Buffer); @H_772_20@
*Buffer = (LPTSTR)LocalAlloc(LPTR, *Length); @H_772_20@
}else { @H_772_20@
return falSE; @H_772_20@
} @H_772_20@
} @H_772_20@
return TRUE; @H_772_20@
} @H_772_20@
/* m_Adapter的数据结构 */ @H_772_20@
typedef struct adapter_info_s { @H_772_20@
char NAME[NAME_LEN]; /* 内部设备名, UUID的字符串形式 */ @H_772_20@
char desc[NAME_LEN]; /* 网卡描述 */ @H_772_20@
char driver[NAME_LEN]; /* 网卡在注册表中的位置, 如{4D36E972-E325-11CE-BFC1-08002BE10318}\0011 @H_772_20@
实际完整的键名为System\\CurrentControlSet\\Control\\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0011 @H_772_20@
该键包含的内容与SetupDiGetDeviceRegistryProperty得到的设备属性基本相同 @H_772_20@
如NetCfgInstancEID即为内部设备名 DriverDesc为设备描述 */ @H_772_20@
int index; @H_772_20@
}adapter_info_t; @H_772_20@
@H_772_20@
/***************************************************************************** @H_772_20@
用何名称区分不同的网卡 @H_772_20@
有如下名称可供选择 @H_772_20@
本地连接名, 这是系统使用的方法, 调用的是netman.dll中的未公开函数HrLanConnectionNameFromGuidOrPath(其原型笔者正在调试之中, 成功之后会另行撰文); 其实也可从注册表中获得HKLM\System\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}\Connection\Name @H_772_20@
网卡类型描述 @H_772_20@
设备友好名 它与网卡类型描述基本相同, 当存在同种类型的网卡, 它会加#n(n = 2, 3, 4...)以示区分 @H_772_20@
如本程序中笔者即以设备友好名区分网卡 @H_772_20@
*****************************************************************************/ @H_772_20@
/* 重启网卡的过程************************************************************/ @H_772_20@
k = pAdapter->Getcursel(); /* m_Adapter[k]即当前网卡 */ @H_772_20@
if (SetupDiEnumDeviceInfo(m_hDevInfo, m_Adapter[k].index ,&deviceInfoData)) @H_772_20@
{ @H_772_20@
hcursor = Setcursor(Loadcursor(NULL, IDC_WAIT)); @H_772_20@
ChangeDeviceState(m_hDevInfo, &deviceInfoData, DicS_DISABLE); /* 禁用网卡 */ @H_772_20@
ChangeDeviceState(m_hDevInfo, DicS_ENABLE); /* 启用网卡 */ @H_772_20@
/* 重启网卡, 一般情况下, 以下命令相当于前两命令的组合. 但我仍建议使用前者 */ @H_772_20@
// ChangeDeviceState(m_hDevInfo, DicS_PROPCHANGE); @H_772_20@
Setcursor(hcursor); @H_772_20@
} @H_772_20@
/* 扫尾工作 */ @H_772_20@
SetupDiDestroyDeviceInfoList(m_hDevInfo); @H_772_20@
总结: 通过网卡重启更改IP的方法有两个步骤: 修改注册表, 重启网卡. 重启网卡的全过程上面已作描述. 注册表修改的内容为文中列出四个主要项, 如{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}的网卡名称即是内部设备名, 在adapter结构中已给出. 整个注册表修改的过程比较简单, 本文不加叙述. @H_772_20@
@H_772_20@
Windows系统中, 更改Windows网卡属性选项中IP地址, 可以即时使更改生效, 并且没有重启网卡的过程. 系统自带的netsh也能通过命令行或脚本文件的形式, 完成更改IP的功能时, 也不需要重启网卡 @H_772_20@
同时也有很多共享软件, 可以实现同样的功能, 常见IP地址更改软件有IPFreeSet, IPChanger, IPProfile, IPHelp, IPSet, SNet等. @H_772_20@
@H_772_20@
笔者通过分析netsh发现一个未公开函数, 即用netcfgx.dll封装的dhcpcsvc.dll中DhcpNotifyConfigChange函数 @H_772_20@
具体的方法参见VCKB 25期 王骏先生的 "不重起Windows直接更改IP地址", 他得到的函数原型比我准确, 思路也很清晰. @H_772_20@
分析上述共享软件时, 发现其技术要点不外乎三种: 使用未公开函数, 调用netsh命令, 重启网卡硬件. 调用netsh命令的实质还是使用未公开函数 @H_772_20@
使用未公开函数的有: IPFreeSet, IPChanger @H_772_20@
调用netsh命令的有 : IPHelp, IPSet. 两者都是用Delphi开发的. @H_772_20@
重启网卡硬件: IPSwitcher @H_772_20@
速度比较: 因为netsh本身的实现是调用netcfgx.dll, netcfgx.dll封装了对未公开函数的使用, 故效率相对较低. 在一台cpu:PIII500/RAM:256/XP的系统中, IPHelp需要6~7秒才能完成, 而IPFreeSet只需要1~2秒. @H_772_20@
@H_772_20@
方法三:一卡多IP @H_772_20@
除以上两个方法外, 笔者再介绍一种方法. 无论是在Windows下还是在Linux下, 一块网卡都可同时具有多个IP地址. 根据TCP/IP原理, 在网络层标识通信节点是IP地址, 在链路层上的则是MAC地址. 只要通过ARP, 将多个IP与@L_212_54@mAC对应起来, 就可实现一网卡多IP(其实是一MAC多Ip). 系统本身也有相应的设置选项, 如windows是通过TCP/IP属性的高级选项添加的, Linux下可由ifconfig命令添加. @H_772_20@
iphlpapi提供AddIpaddress和DelIpaddress. 如果能先加入新的IP, 再去除原来的IP, 即可实现IP地址的更改. @H_772_20@
具体内容参见我下篇文章"iphlpapi"的使用@H_772_20@
————————————————@H_772_20@
版权声明:本文为CSDN博主「笨笨D幸福」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。@H_772_20@
原文链接:https://blog.csdn.net/bbdxf/article/details/7548443@H_772_20@
以上是大佬教程为你收集整理的在程序中修改IP win7 winXP(参考1)全部内容,希望文章能够帮你解决在程序中修改IP win7 winXP(参考1)所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。