加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

在程序中修改IP win7 winXP(参考1)

发布时间:2020-12-14 05:55:08 所属栏目:Windows 来源:网络整理
导读:https://blog.csdn.net/bbdxf/article/details/7548443 Windows下程序修改IP的三种方法 ????以下讨论的平台依据是Window?XP?+?SP1,?不考虑Windows其它版本的兼容性问题,?但对NT系列的系统,?理论上是通用的.? 方法一:?网卡重启? ????更改Windows网卡属性选项

https://blog.csdn.net/bbdxf/article/details/7548443

Windows下程序修改IP的三种方法

????以下讨论的平台依据是Window?XP?+?SP1,?不考虑Windows其它版本的兼容性问题,?但对NT系列的系统,?理论上是通用的.?

方法一:?网卡重启?
????更改Windows网卡属性选项中IP地址,?通过对比前后注册表,?可以发现以下几处发生变化?
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParametersInterfaces{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}]?
"IPAddress"?
"SubnetMask"?
"DefaultGateway"?
"NameServer"?

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}ParametersTcpip]?
"IPAddress"?
"SubnetMask"?
"DefaultGateway"?

[HKEY_LOCAL_MACHINESYSTEMControlSet001ServicesTcpipParametersInterfaces{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_MACHINESYSTEMCurrentControlSetServicesTcpipParametersInterfaces{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}]?
"IPAddress"?
"SubnetMask"?
"DefaultGateway"?
"NameServer"?
????是主要的设置处.?

[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}ParametersTcpip]?
"IPAddress"?
"SubnetMask"?
"DefaultGateway"?
????对一些服务有影响,?如不设置,?用netstat可以看到原来的IP地址仍处于监听状态(?).?

????但为了使设置生效,?还有很重要的一步,?即重启网卡.?

????更改网卡的配置,?一般而言需要重启网卡,?如?
????Linux系统,?只需运行?
????????#ifconfig?eth0?down?
????????#ifconfig?eht0?up?
????就可以实现网卡的重启.?

????Windows环境下的步骤与之类似:?先禁用本地连接(网卡),?再启用本地连接(网卡).?但没有相应的命令或者直接的API.?所幸的是DDK提供一套设备安装函数,?用于控制系统设备,?包括控制设备的状态改变.?

/****************************************************************************************?
?Purpose:????change?state?of?the?selected?device?
?Input????:????hDevInfo????device?info?set?????
????????????pDeviceInfoData????????selected?device?info?
????????????NewState????one?of?enable/disable?
?Output????:????TRUE?for?success,?FALSE?for?failed?
?****************************************************************************************/?
BOOL?ChangeDeviceState(HDEVINFO?hDevInfo,?PSP_DEVINFO_DATA?pDeviceInfoData,?DWORD?NewState)?
{?
????SP_PROPCHANGE_PARAMS?PropChangeParams?=?{sizeof(SP_CLASSINSTALL_HEADER)};?
????SP_DEVINSTALL_PARAMS?devParams;?

????if?(!pDeviceInfoData)?{?
????????return?FALSE;?
????}?

????PropChangeParams.ClassInstallHeader.cbSize?=?sizeof(SP_CLASSINSTALL_HEADER);?
????PropChangeParams.ClassInstallHeader.InstallFunction?=?DIF_PROPERTYCHANGE;?
????PropChangeParams.Scope?=?DICS_FLAG_CONFIGSPECIFIC;?
????PropChangeParams.StateChange?=?NewState;??
????PropChangeParams.HwProfile?=?0;?

????if?(!SetupDiSetClassInstallParams(hDevInfo,pDeviceInfoData,?
??????(SP_CLASSINSTALL_HEADER?*)&PropChangeParams,sizeof(PropChangeParams))?
??????||?!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,hDevInfo,pDeviceInfoData))????{?
????????return?FALSE;?
????}?
????reutrn?TRUE;?
}?

/*?hDevInfo如何得到***********************************************************/?
????m_hDevInfo?=?SetupDiGetClassDevs(?
??????(LPGUID)?&GUID_DEVCLASS_NET,????/*?GUID_DEVCLASS_NET表示仅列出网络设备?*/?
??????NULL,??
??????this->m_hWnd,??
??????DIGCF_PRESENT);?
????if?(INVALID_HANDLE_VALUE?==?m_hDevInfo)?{?
????????return?FALSE;?
????}?

/*?pDeviceInfoData如何得到**************************************************/?
????k?=?0;?
????while?(SetupDiEnumDeviceInfo(m_hDevInfo,?k?,&DeviceInfoData))????{?
????????k++;?
????????if?(CR_SUCCESS?!=?CM_Get_DevNode_Status(&Status,?&Problem,??
??????????DeviceInfoData.DevInst,0))?{?
????????????continue;?
????????}?
????????if?((Status?&?DN_NO_SHOW_IN_DM))?{?
????????????continue;?
????????}?
????????if?(GetRegistryProperty(m_hDevInfo,?
??????????&DeviceInfoData,?
??????????SPDRP_FRIENDLYNAME,?
??????????&pBuffer,?
??????????&Length))?{?
????????????m_Adapter[adapter_num].index?=?k?-?1;????????/*?当前网卡在设备信息集中的索引?*/?
????????????_tcscpy(m_Adapter[adapter_num].desc,?pBuffer);????/*?当前网卡?*/?
????????????GetRegistryProperty(m_hDevInfo,?
??????????????&DeviceInfoData,?
??????????????SPDRP_DRIVER,?
??????????????&pBuffer,?
??????????????&Length);?
????????????_tcscpy(m_Adapter[adapter_num].driver,?pBuffer);?
????????????adapter_num++;?
????????}?
????}?

/*?GetRegistryProperty是对SetupDiGetDeviceRegistryProperty封装***************/?
BOOL?GetRegistryProperty(HDEVINFO??DeviceInfoSet,?
?????????????????????????PSP_DEVINFO_DATA??DeviceInfoData,?
?????????????????????????ULONG?Property,?
?????????????????????????LPTSTR*?Buffer,?
?????????????????????????PULONG?Length)?
{?
????while?(!SetupDiGetDeviceRegistryProperty(?
????????DeviceInfoSet,?
????????DeviceInfoData,?
????????Property,?
????????NULL,?
????????(PBYTE)(*Buffer),?
????????*Length,?
????????Length?
????????))?
????{?
????????if?(GetLastError()?==?ERROR_INSUFFICIENT_BUFFER)?{?
????????????if?(*(LPTSTR?*)Buffer)??
????????????????LocalFree(*(LPTSTR?*)Buffer);?
????????????*Buffer?=?(LPTSTR)LocalAlloc(LPTR,?*Length);?
????????}else?{?
????????????return?FALSE;?
????????}?????????????
????}?
????return?TRUE;?
}?


/*?m_Adapter的数据结构?*/?
typedef?struct?adapter_info_s?{?
????char?name[NAME_LEN];????????/*?内部设备名,?UUID的字符串形式?*/?
????char?desc[NAME_LEN];????????/*?网卡描述?*/?
????char?driver[NAME_LEN];????????/*?网卡在注册表中的位置,?如{4D36E972-E325-11CE-BFC1-08002BE10318}011??
????实际完整的键名为SystemCurrentControlSetControlClass{4D36E972-E325-11CE-BFC1-08002BE10318}011??
????该键包含的内容与SetupDiGetDeviceRegistryProperty得到的设备属性基本相同?
????如NetCfgInstanceId即为内部设备名?DriverDesc为设备描述????*/?
????int?index;?
}adapter_info_t;?
?????


/*****************************************************************************?
?用何名称区分不同的网卡?
?有如下名称可供选择?
????本地连接名,?这是系统使用的方法,?调用的是netman.dll中的未公开函数HrLanConnectionNameFromGuidOrPath(其原型笔者正在调试之中,?成功之后会另行撰文); 其实也可从注册表中获得HKLMSystemCurrentControlSetControlNetwork{4D36E972-E325-11CE-BFC1-08002BE10318}{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}ConnectionName?
????网卡类型描述?
????设备友好名????????它与网卡类型描述基本相同,?当存在同种类型的网卡,?它会加#n(n?=?2,?3,?4...)以示区分?
????如本程序中笔者即以设备友好名区分网卡?
?*****************************************************************************/?

/*?重启网卡的过程************************************************************/?
????k?=?pAdapter->GetCurSel();????????/*?m_Adapter[k]即当前网卡?*/?
????if?(SetupDiEnumDeviceInfo(m_hDevInfo,?m_Adapter[k].index?,&DeviceInfoData))?
????{?
????????hCursor?=?SetCursor(LoadCursor(NULL,?IDC_WAIT));?????????
????????ChangeDeviceState(m_hDevInfo,?&DeviceInfoData,?DICS_DISABLE);????/*?禁用网卡?*/?????????
????????ChangeDeviceState(m_hDevInfo,?DICS_ENABLE);????/*?启用网卡?*/?????????
????????/*?重启网卡,?一般情况下,?以下命令相当于前两命令的组合.?但我仍建议使用前者?*/?????
????????//????ChangeDeviceState(m_hDevInfo,?DICS_PROPCHANGE);?
????????SetCursor(hCursor);?????
????}?

/*?扫尾工作?*/?
????SetupDiDestroyDeviceInfoList(m_hDevInfo);?

????总结:?通过网卡重启更改IP的方法有两个步骤:?修改注册表,?重启网卡.?重启网卡的全过程上面已作描述.??注册表修改的内容为文中列出四个主要项,?如{97EFDAD8-EB2D-4F40-9B07-0FCD706FCB6D}的网卡名称即是内部设备名,?在adapter结构中已给出.?整个注册表修改的过程比较简单,?本文不加叙述.?

?

方法二:未公开函数?

????Windows系统中,?更改Windows网卡属性选项中IP地址,?可以即时使更改生效,?并且没有重启网卡的过程.?系统自带的netsh也能通过命令行或脚本文件的形式,?完成更改IP的功能时,?也不需要重启网卡?
????同时也有很多共享软件,?可以实现同样的功能,?常见IP地址更改软件有IPFreeSet,?IPChanger,?IPProfile,?IPHelp,?IPSet,?SNet等.?
?????
????笔者通过分析netsh发现一个未公开函数,?即用netcfgx.dll封装的dhcpcsvc.dll中DhcpNotifyConfigChange函数?
????具体的方法参见VCKB?25期?王骏先生的?"不重起Windows直接更改IP地址",?他得到的函数原型比我准确,?思路也很清晰.?


分析上述共享软件时,?发现其技术要点不外乎三种:?使用未公开函数,?调用netsh命令,?重启网卡硬件.?调用netsh命令的实质还是使用未公开函数?

使用未公开函数的有:?IPFreeSet,?IPChanger?
调用netsh命令的有?:?IPHelp,?IPSet.?两者都是用Delphi开发的.?
重启网卡硬件:?IPSwitcher?

速度比较:?因为netsh本身的实现是调用netcfgx.dll,?netcfgx.dll封装了对未公开函数的使用,?故效率相对较低.?在一台CPU:PIII500/RAM:256/XP的系统中,?IPHelp需要6~7秒才能完成,?而IPFreeSet只需要1~2秒.?

?

方法三:一卡多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地址的更改.?
????具体内容参见我下篇文章"iphlpapi"的使用
————————————————
版权声明:本文为CSDN博主「笨笨D幸福」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bbdxf/article/details/7548443

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读