之前曾在这里问过我的问题,但我正在尝试为我的项目实施更整洁的解决方案。因此,正如标题所述,我正在创建服务器应用程序的复杂安装程序,该安装程序必须检查本地IP地址并选择一个开放端口,以便可以正确配置该应用程序。使用了Inno Setup 5.6.1。
获取本地IP地址不是问题,this solution对我有很大帮助。然后到了端口的检查,在这里我发现了以下三个选项:
如上所述,获取IP地址可以通过简单的WinAPI调用(好吧,不是真的,这是一个Pascal脚本)来实现。因此,我尝试使用端口进行相同的技巧,尝试调用GetTcpTable()
:
[Code]
const
ERROR_INSUFFICIENT_BUFFER = 122;
function GetTcpTable(pTcpTable: Array of Byte; var pdwSize: Cardinal;
bOrder: WordBool): DWORD;
external 'GetTcpTable@IpHlpApi.dll stdcall';
{ ------------------------ }
function CheckPortIsOpen(port: Integer): Boolean;
var
TableSize : Cardinal;
Buffer : Array of Byte; { Alas, no pointers here }
RecordCount : Integer;
i, j : Integer;
portNumber : Cardinal;
IpAddr : String;
begin
Result := True;
TableSize := 0;
if GetTcpTable(Buffer, TableSize, False) = ERROR_INSUFFICIENT_BUFFER then
begin
SetLength(Buffer, TableSize);
if GetTcpTable(Buffer, TableSize, True) = 0 then
begin
{ some magic calculation from GetIpAddrTable calling example }
RecordCount := (Buffer[1] * 256) + Buffer[0];
For i := 0 to RecordCount -1 do
begin
portNumber := Buffer[i*20 + 8]; { Should work! }
{ Debugging code here }
if (i < 5) then begin
IpAddr := '';
For J := 0 to 3 do
begin
if J > 0 then
IpAddr := IpAddr + '_';
IpAddr := IpAddr + IntToStr(Buffer[I*20+ 4 + J]);
end;
SuppressibleMsgBox(IpAddr, mbError, MB_OK, MB_OK);
end;
{ ------ }
if port = portNumber then
Result := False;
end;
end;
end;
end;
此GetTcpTable
还返回有关地址和端口(准确地说是TCP连接表)的信息,因此,尝试获取任何连接地址都有助于调试。有关此尝试的更多信息:
RecordCount
的计算方式与我作为示例的代码相同,因为obtained struct there与the nasty struct I need非常相似。i*20 + 8
是因为20 = sizeof(single record struct)和8 = 2 * sizeof(DWORD)
。如您所见,本地TCP连接地址正以1个DWORD的偏移量被“解析”一个字节。所以,一切都非常有趣...它根本不起作用=((
是的,我尝试逐个打印 all 个字节,以便手动搜索所需的数据并了解正确的偏移量。令我失望的是,没有找到看起来像IP和端口的东西,这些数字非常神秘。
我知道有时候最简单的解决方案是最好的,而不是最聪明的解决方案,但是如果有人可以正确地使用此WinAPI函数,我将不胜感激。
答案 0 :(得分:2)
您的魔术计算已关闭。
pg_hba.conf
由于portNumber := Buffer[i*20 + 8]; { Should work! }
是一个字节数组,因此上面仅提取一个字节。但是本地端口号在TCP表中是Buffer
。尽管您链接的文档指出:
本地网络上TCP连接的本地端口号,以网络字节顺序显示。
IP端口号的最大大小为16位,因此仅应使用低16位。高16位可能包含未初始化的数据。
所以我们需要两个字节。并且我们需要切换它们,注意上面的“网络字节顺序”。
您还忘记在表的开头考虑4字节记录数。因此,本地端口号应变为:
DWORD