查看: 156|回复: 0

[教程] 最新NSIS检测端口是否被占用

[复制链接]
  • TA的每日心情
    开心
    2019-11-1 10:07
  • 签到天数: 10 天

    [LV.3]偶尔看看II

    1

    主题

    6

    帖子

    142

    积分

    积分
    142
    发表于 2019-10-18 14:49:22 | 显示全部楼层 |阅读模式
    本帖最后由 Jabeen 于 2019-10-18 14:51 编辑

    背景:论坛中的文章【NSIS检测端口是否被占用】https://www.nsisfans.com/thread-723-1-1.html,
    参考论坛的做法,但是结果根本不对:

    1.png
    命令查看8089端口是否被占用,这个是没有被占用的,然后用上面文章中的NSIS脚本检查:
    2.png
    8089端口被占用,但实际上电脑上的8089端口根本没有开启。

    问题原因:
    脚本中用的是LogicLib.nsh插件,感觉是这个插件问题。

    解决方案:
    参考NSIS官网有插件Check open portshttps://nsis.sourceforge.io/Check_open_ports
    完整代码如下:
    PortCheck.nsi
    1. # ===================== Create by Jabeen.huangyi 2019-10-18 =====================
    2. # ===================== 检测端口是否被占用 =====================
    3. Name PortCheck
    4. OutFile PortCheck.exe

    5. !include Ports.nsh

    6. Var Port

    7. Section
    8.     StrCpy $Port 8089
    9.     ;判断TCP端口是否被占用(用这个来判断tomcat,mysql端口是否被占用)
    10.     Push "Tcp"
    11.     Push $Port
    12.     Call IsPortOpen
    13.     Pop $0 ; "open" or "closed" or anything else for error
    14.     ${If} $0 == "open"
    15.         MessageBox MB_OK "TCP端口:$Port 被占用"
    16.     ${EndIf}

    17.     ;判断UDP端口是否被占用
    18.     Push "Udp"
    19.     Push $Port
    20.     Call IsPortOpen
    21.     Pop $0 ; "open" or "closed" or anything else for error
    22.     ${If} $0 == "open"
    23.         MessageBox MB_OK "UDP端口:$Port 被占用"
    24.     ${EndIf}
    25. SectionEnd
    复制代码


    Ports.nsh
    1. # Usage:
    2. #   Push "Tcp" or "Udp"
    3. #   Push "port_number"
    4. #   Call IsPortOpen
    5. #   Pop $0 ; "open" or "closed" or anything else for error
    6. #
    7. # Or with the LogicLib
    8. #   ${If} ${TCPPortOpen} 80
    9. #   ${EndIf}
    10. #   ${If} ${UDPPortOpen} 137
    11. #   ${EndIf}
    12. #
    13. Function IsPortOpen

    14.   Exch $R0 # port to check
    15.   Exch
    16.   Exch $R1
    17.   Push $0
    18.   Push $1
    19.   Push $2

    20.   System::Call 'iphlpapi::Get$R1Table(*i.r0, *i .r1, i 1) i .r2'
    21.   ${If} $2 != 122 # ERROR_INSUFFICIENT_BUFFER
    22.     StrCpy $R0 ""
    23.     Pop $2
    24.     Pop $1
    25.     Pop $0
    26.     Exch $R1
    27.     Exch
    28.     Exch $R0
    29.     Return
    30.   ${EndIf}

    31.   System::Alloc $1
    32.   Pop $0

    33.   System::Call 'iphlpapi::Get$R1Table(ir0, *i r1, i 1) i .r2'
    34.   ${If} $2 != 0 # NO_ERROR
    35.     System::Free $0
    36.     StrCpy $R0 ""
    37.     Pop $2
    38.     Pop $1
    39.     Pop $0
    40.     Exch $R1
    41.     Exch
    42.     Exch $R0
    43.     Return
    44.   ${EndIf}

    45.   Push $3
    46.   Push $4
    47.   Push $5

    48.   System::Call *$0(i.r2)
    49.   IntOp $2 $2 - 1
    50.   ${For} $3 0 $2
    51.     IntOp $4 $0 + 4  # skip dwNumEntries
    52.     ${If} $R1 == "Tcp"
    53.       IntOp $5 $3 * 20 # sizeof(MIB_TCPROW)
    54.       IntOp $4 $4 + $5 # skip to entry
    55.       System::Call *$4(i.r1,i,i.r4,i,i)
    56.       ${If} $1 <> 2  # $1 = dwState, 2 = MIB_TCP_STATE_LISTEN
    57.         ${Continue}
    58.       ${EndIf}
    59.     ${Else}
    60.       IntOp $5 $3 * 8 # sizeof(MIB_UDPROW)
    61.       IntOp $4 $4 + $5 # skip to entry
    62.       System::Call *$4(i,i.r4)
    63.     ${EndIf}
    64. !if "${NSIS_PACKEDVERSION}" >= 50343936 ; v3.3+
    65.     System::Call ws2_32::ntohs(hr4)h.r4
    66. !else
    67.     System::Call ws2_32::ntohs(ir4)i.r4
    68.     IntOp $4 $4 & 0xffff ; Truncate to 16-bits
    69. !endif

    70.     ${If} $4 = $R0
    71.       StrCpy $R0 "open"
    72.       ${Break}
    73.     ${EndIf}
    74.   ${Next}

    75.   ${If} $R0 != "open"
    76.     StrCpy $R0 "closed"
    77.   ${EndIf}

    78.   System::Free $0

    79.   Pop $5
    80.   Pop $4
    81.   Pop $3
    82.   Pop $2
    83.   Pop $1
    84.   Pop $0
    85.   Exch $R1
    86.   Exch
    87.   Exch $R0

    88. FunctionEnd

    89. # LogicLib macros for IsPortOpen

    90. !include LogicLib.nsh

    91. !macro _PortOpen _a _b _t _f
    92.   !insertmacro _LOGICLIB_TEMP
    93.   Push `${_a}`
    94.   Push `${_b}`
    95.   Call IsPortOpen
    96.   Pop $_LOGICLIB_TEMP
    97.   !insertmacro _== $_LOGICLIB_TEMP "open" `${_t}` `${_f}`
    98. !macroend
    99. !define PortOpen `PortOpen`

    100. !macro _TCPPortOpen _a _b _t _f
    101.   !insertmacro _PortOpen Tcp `${_b}` `${_t}` `${_f}`
    102. !macroend
    103. !define TCPPortOpen `"" TCPPortOpen`

    104. !macro _UDPPortOpen _a _b _t _f
    105.   !insertmacro _PortOpen Udp `${_b}` `${_t}` `${_f}`
    106. !macroend
    107. !define UDPPortOpen `"" UDPPortOpen`
    复制代码


    注意:PortCheck.nsi脚本中我这里没有用LogicLib的使用示例,就是${If} ${TCPPortOpen} 80这样的写法,因为在测试的时候发现,测试结果也是错误的。







    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    Archiver|手机版|小黑屋|联系我们|NSIS中文论坛    

    GMT+8, 2019-11-12 09:26 , Processed in 0.020738 second(s), 15 queries , MemCache On.

    Powered by Discuz! X3.3

    © 2001-2019 Comsenz Inc.

    快速回复 返回顶部 返回列表