如何使用Inno Setup获取本地IP地址

12

如何使用Inno Setup获取用户本地IP地址?

我考虑使用Win32 API GetIpAddrTable,但不清楚如何进行调整。

是否有其他方式可以获取IP地址?或者知道如何操作?


使用Inno Setup是什么意思? - opc0de
1
@opc0de:他可能正在编写Inno Setup脚本。Inno Setup支持Pascal脚本。 - Andreas Rejbrand
在安装过程中,我需要向用户显示本地IP地址列表(如果他有多个物理或逻辑网络卡),并让用户从IP地址列表中进行选择。 - Toda Raba
1
我可以建议不要在安装程序中添加此功能,这样做是浪费时间。相反,启动一个UI界面,让用户配置实用程序。稍后,用户将希望再次运行相同的选项。您想让他们重新安装以更改此选项吗?如果用户的IP在安装后更改了怎么办? - Warren P
6
取决于你需要 IPv4 地址还是 IPv6 地址。另外,一台机器可以拥有多个本地 IP 地址。 - Robert Love
4
@Toda,如果我在连接旅馆的WiFi网络时安装了您的软件,然后回家后尝试在有线网络上使用该软件会发生什么?提示:IP地址会发生变化,不要在安装时询问IP地址。适配器信息可能也不足够(如果我配置了VPN或插入USB WiFi dongle,或者使用手机的蓝牙连接)。如果您的应用程序如此严重地依赖于网络设备和地址,那么它就是为“高级用户”设计的,他们肯定要求能够在运行时选择IP或适配器。 - Cosmin Prund
2个回答

22

这取决于您是想获取IPv4地址还是IPv6地址。但是由于您提到了 GetIpAddrTable,而它只返回IPv4地址,所以我猜测这就是您想要的。

每台计算机可以拥有多个本地IP地址。因此我将它们作为 TStringList 返回。
我在以下测试的计算机上有5个IP地址。

由于Inno Setup不支持指针,所以我必须通过一个Array of Byte缓冲区完成所有操作。

下面的代码是一个完整的Inno Setup脚本,演示如何使用此函数。

[Setup]
AppName=Test
AppVersion=1.5
DefaultDirName={pf}\test

[Code]

const
 ERROR_INSUFFICIENT_BUFFER = 122;


function GetIpAddrTable( pIpAddrTable: Array of Byte;
  var pdwSize: Cardinal; bOrder: WordBool ): DWORD;
external 'GetIpAddrTable@IpHlpApi.dll stdcall';


procedure GetIpAddresses(Addresses : TStringList);
var 
 Size : Cardinal;
 Buffer : Array of Byte;
 IpAddr : String;
 AddrCount : Integer;
 I, J : Integer;
begin
  { Find Size }
  if GetIpAddrTable(Buffer,Size,False) = ERROR_INSUFFICIENT_BUFFER then
  begin
     { Allocate Buffer with large enough size }
     SetLength(Buffer,Size);
     { Get List of IP Addresses into Buffer }
     if GetIpAddrTable(Buffer,Size,True) = 0 then
     begin
       { Find out how many addresses will be returned. }
       AddrCount := (Buffer[1] * 256) + Buffer[0];
       { Loop through addresses. }
       For I := 0 to AddrCount - 1 do
       begin
         IpAddr := '';
         { Loop through each byte of the address }
         For J := 0 to 3 do
         begin
           if J > 0 then
             IpAddr := IpAddr + '.';
           { Navigate through record structure to find correct byte of Addr }
           IpAddr := IpAddr + IntToStr(Buffer[I*24+J+4]);
         end;
         Addresses.Add(IpAddr);
       end;
     end;
  end;
end;

function InitializeSetup(): Boolean;
var
 SL : TStringList;
begin
  SL := TStringList.Create;
  GetIpAddresses(SL);
  MsgBox(SL.Text, mbInformation, MB_OK);
  SL.Free;
end;

是的,+1,但我个人仍然会尽可能将所有实用程序代码移出脚本(并放入辅助 DLL 中)。安装程序脚本不太容易扩展,为了可读性/可维护性,请保持它们简洁明了。 - Paul-Jan
1
为什么我用这段代码会出现“未知类型'WordBool'”的错误? - hram908
第13行第34列:未知类型“WordBool”。 - hram908
@hram908,我猜你正在使用 ANSI 版本,而我正在使用 Unicode 版本。 - Robert Love
@Robert Love,我们的猜测是正确的。Unicode 是正确的选择!谢谢。 - hram908
显示剩余5条评论

8
构建一个外部 DLL,返回一个IP地址列表,并在Inno Setup脚本中读取该列表。
这篇文章中,您会找到构建DLL以及如何在InnoSetup脚本中调用它的代码示例。
这篇SO帖子中,您将学习如何使用Indy库或纯WinApi获取IP地址。

2
不需要创建外部DLL,InnoSetup可以直接调用API。 - Robert Love

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接