注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

鑫淼梦园的博客

圆你的梦想 从这里开始

 
 
 

日志

 
 

Delphi中编程控制系统IP配置(转)  

2014-10-05 19:00:49|  分类: delphixe7 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
摘要:主要论述了如何运用Delphi编程实现自动释放、自动获得本地系统所有动态IP地址,以及在Delphi中如何使用Netsh.exe实用程序更改网络配置信息,并给出了相应的示例程序。
关键词:Delphi,IP地址,Netsh
一、 引言 
     随着Internet的普及,网络安全问题日益突出,根据国家有关部门的政策,在大多数安全程度要求高的机关单位都建立了物理隔离的内、外网络。在这种环境下,各工作站需在不同网段的内、外网之间频繁切换,这就要求工作站系统的网络配置需要及时更新。另外,随着移动办公的普及,笔记本电脑系统的网络配置同样需要经常改变。Delphi作为最优秀的开发工具,用“Delphi + Windows API”模式可很好地解决这些问题。  
二、原理
   IP Helper 是一套用于管理本地网络设置的API(应用程序编程接口),这些API函数在iphlpapi.dll库文件中被定义。iphlpapi.dll库文件存在于Windows NT4/2000\System32 目录下或Windows 98/Me 的 \System目录。就象在VC中编写头文件一样,在delphi中使用这些API需要进行相应的定义和声明。
一台计算机可能安装一块以上网络适配器或存在Modem,调用GetAdaptersInfo函数可获得当前计算机网络配置信息。这个函数包含两个参数,第一个参数是用来保存适配器信息的内存缓冲的首地址,而第二个参数是这个缓冲的大小。由于我们事先不知道本地机器上有多少个网络适配器,所以也就没法知道应该分配多大的缓存,好在GetAdaptersInfo函数在缓冲的大小不够时会在第二个参数中填入应该分配的缓冲的大小,因此,就象其它一些函数一样在需要时我们可以两次调用该函数,第一次是获取缓冲区的大小,然后分配这个缓冲以后再次调用它以获得实际的网卡信息。函数定义如下:
function GetAdaptersInfo( pAdapterInfo: PTIP_ADAPTER_INFO;pOutBufLen: PULONG ): DWORD;
stdcall; external 'IPHLPAPI.DLL';
函数返回的当前计算机网络配置信息存在于第一个参数pAdapterInfo指向的IP_ADAPTER_INFO结构,该数据结构是以静态链表的方式组织的。
PIpAdapterInfo = ^TIpAdapterInfo;
  TIP_ADAPTER_INFO = record
  Next: PIpAdapterInfo; //链表指针域,通过它访问整个静态键表
  ComboIndex: DWORD; //保留未用
  AdapterName: //网卡名,max_adapter_name_length=256
  array [0..MAX_ADAPTER_NAME_LENGTH + 3] of Char;
  Description: //对网卡的描述max_adapter_description_length=128
  array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of Char;
  AddressLength: UINT; //物理地址的长度
  Address: //物理地址,max_adapter_address_length=8每个字节存放一个十六进制的数
  array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;
  Index: DWORD; //网卡索引号
  Type_: UINT; //网卡类型
  DhcpEnabled: UINT; //是否启用了DHCP动态IP分配
  CurrentIpAddress: PIP_ADDR_STRING; //当前使用的IP地址
  IpAddressList: IP_ADDR_STRING; //绑定到此网卡的IP地址链表
  GatewayList: IP_ADDR_STRING; //网关地址链表
  DhcpServer: IP_ADDR_STRING; //DHCP服务器地址,只有在DhcpEnabled==TRUE的情况下才有效
  HaveWins: BOOL; //是否启用了WINS
  PrimaryWinsServer: IP_ADDR_STRING; //主WINS地址
  SecondaryWinsServer: IP_ADDR_STRING; //辅WINS地址
  LeaseObtained: time_t; //当前DHCP租借获取的时间
  LeaseExpires: time_t; //当前DHCP租借失效时间
end;
这些数据就是网络属性→TCP/IP的属性页里的内容。使用这些信息可进行网络配置信息的更改,下面说明如何更新动态IP和修改静态网络配置信息。
2.1 DhcpEnabled = 1 则说明本地IP为DHCP服务器动态分配,调用IpReleaseAddress和IpRenewAddress可释放、重新获得系统IP地址。函数定义如下:
function IpRenewAddress(var AdapterInfo: TIP_ADAPTER_INDEX_MAP): DWORD;stdcall; external 'IPHLPAPI.DLL';
function IpReleaseAddress(var AdapterInfo: TIP_ADAPTER_INDEX_MAP): DWORD;stdcall;external 'IPHLPAPI.DLL';
使用这两个函数必需获取网络接口信息,以指定释放、更新IP地址的适配器索引号。一个网络接口是网卡的逻辑抽象,它们是一对一的关系。注意调用GetNumberOfInterfaces函数返回本机接口的数量,实际上比网络接口数目多一个,因为每个系统都附加有一个调试用的网络接口,这个接口的IP地址是127.0.0.1子网掩码是255.0.0.0。GetInterfaceInfo函数提取网络接口的信息:
function GetInterfaceInfo(pIfTable: PTIP_INTERFACE_INFO;dwOutBufLen: PULONG): DWORD;
stdcall; external 'IPHLPAPI.DLL';
它返回IP_INTERFACE_INFO结构中有一个NumAdapters整型的数据域记录了当前本机适配器数量,Adapter为IP_ADAPTER_INDEX_MAP结构的数据数组。

PIP_INTERFACE_INFO = ^TIP_INTERFACE_INFO;
TIP_INTERFACE_INFO = record
    NumAdapters : Longint;
    Adapter : array [0..1-1] of IP_ADAPTER_INDEX_MAP;
end;

其中的IP_ADAPTER_INDEX_MAP结构如下:
PIpAdapterIndexMap = ^TIpAdapterIndexMap;
TIP_ADAPTER_INDEX_MAP = record
    Index: ULONG;
    Name: array [0..127] of WCHAR;
end;

当此结构中Index值等于通过调用GetAdaptersInfo函数pAdapterInfo指向的结构中Index域的值,说明网络适配器和网络接口相匹配,就可调用IpReleaseAddress和IpRenewAddress进行释放、重新获得该适配器IP地址。
2.2 在Delphi中通过直接使用Netsh.exe实用程序可改变windows2000/XP系统的IP网络配置信息。
三、程序实现
    3.1 在WIN98中运行Winipcfg实用程序, 在windows2000/XP中运行Ipconfig可释放、重新获得系统(所有)IP地址。下面用Delphi编程实现:
首先声明Public IndexStrs : Tstrings; //保存本机所有网卡索引号
procedure TForm1.Button1Click(Sender: TObject);
var
  Err, BufLen : DWORD;
  P : Pointer;
AdapterInfo : PTIP_ADAPTER_INFO;
begin
  BufLen := SizeOf( AdapterInfo^ );
  New( AdapterInfo );
  Err := GetAdaptersInfo( AdapterInfo, @BufLen );
  P := AdapterInfo;
  IndexStrs:=Tstringlist.Create;
if Err =NO_ERROR then
begin
  while P <> nil do
  with TIP_ADAPTER_INFO(P^) do
  begin
    if DHCPEnabled = 1 then
    IndexStrs.Add(inttostr(index));
    P := Next; // TIP_ADAPTER_INFO(P^).Next
  end // with
end // while
else
showmessage( SysErrorMessage( Error ) );
  Dispose( AdapterInfo );
end;
Button1的Click事件:当本地IP为DHCP服务器动态分配时把本地机器所有网卡索引号存于TStrings类型IndexStrs中。
procedure TForm1.Button2Click(Sender: TObject);
var
  Res, Err,Suc,BufSize : DWORD;
  ip_map: TIP_ADAPTER_INDEX_MAP;
  cnt,dwIndex,i :Longint;
InterfaceInfo:PTIP_INTERFACE_INFO;
begin
  BufSize :=sizeof(Interfaceinfo^);
  Interfaceinfo := AllocMem(BufSize);
  Err:= Getinterfaceinfo(Interfaceinfo,@BufSize);
  if Err = ERROR_INSUFFICIENT_BUFFER then
begin
  Freemem(Interfaceinfo);
  Interfaceinfo := Allocmem(Bufsize);
  try
Res := GetInterfaceInfo(InterfaceInfo, @BufSize);
if Res = NO_ERROR then
begin
for i:=0 to IndexStrs.Count-1 do
begin
dwindex:=StrToInt(IndexStrs[i]);
for Cnt := 0 to InterfaceInfo^.NumAdapters - 1 do
if InterFaceInfo^.Adapter[cnt].index = dwIndex then
Suc := IpReleaseAddress(InterFaceInfo^.Adapter[cnt]);
if Suc = NO_ERROR then showmessage(' 释放IP成功! ');
end; // for i:=0 to...释放所有IP
for i:=0 to IndexStrs.Count-1 do
begin
dwindex:=StrToInt(IndexStrs[i]);
for Cnt := 0 to InterfaceInfo^.NumAdapters - 1 do
if InterFaceInfo^.Adapter[cnt].index = dwIndex then
Suc := IpReNewAddress(InterFaceInfo^.Adapter[cnt]);
if Suc = NO_ERROR then showmessage(' 重新获得IP成功! ');
end; // for i:=0 to...重新获得所有IP
end;
finally
FreeMem(InterFaceInfo);
end;
end;
IndexStrs.Free;
end;
Button2的Click事件:用IndexStrs中的值匹配网络接口信息中Index,找到相应的适配器释放IP地址,通过循环释放、重新获得所有IP地址。
3.2 在Delphi中使用Netsh 实用程序改变网络配置。
在Windows2000以后的操作系统中都提供了Netsh.exe实用程序。Netsh 是一种命令行实用程序,一般从命令提示符启动 netsh 并更改到包含要使用的命令的上下文,可用来显示或修改当前正在运行的计算机的网络配置,下面说明在Delphi中使用它改变网络配置。
procedure TForm1.Button3Click(Sender: TObject);
begin
ShellExecute(Handle, 'open', 'netsh', PChar('interface ip set address "本地连接" static 192.168.0.10 255.255.255.0 192.168.0.1 1'), nil, SW_HIDE);
end;
无论当前系统IP地址是动态还是静态,Button3Click事件把当前网络配置改为静态IP地址192168.0.10,子网掩码255.255.255.0,网关:192.168.0.1,跃点数:1;同样执行ShellExecute(Handle, 'open', 'netsh', PChar('interface ip set address "本地连接" dhcp'), nil, SW_HIDE)把本地IP地址改为动态。netsh功能强大,通过此种形式可修改、删除、增加DNS、WINS、gateway等网络配置信息,而且更改的信息直接生效,不需要“禁用”→“启用” 网卡或重新启动windows。

四、结束语
    实际上通过修改系统注册表也可改变系统的IP地址等网络配置。不同版本操作系统网络配置信息在注册表中的位置不同。针对win95、win98系统的静态IP地址通过修改注册表来改变IP配置信息,不过所有通过修改系统注册表项改变的IP配置信息需经过 “禁用”→“启用” 网卡或重新启动windows才能生效。另外值得注意的是IP Help API针对win95无效。
参考文献:
[1] PlatForm SDK: IP Helper. http://msdn.microsoft.com/library/default.asp [DB/OL],2004 – 01.
[2] Steve Teixeira,Xavier Pacheco. Delphi 5开发人员指南[M]. 任旭钧等译.北京:机械工业出版社,2000.
  评论这张
 
阅读(313)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017