Loading

NSIS 脚本,安装时添加防火墙规则

场景

在 Windows 上运行需要访问网络或者提供网络服务的程序,需要防火墙放行。默认情况下,在首次运行程序时,可能会有如下弹窗,只有用户点击运行才能继续使用网络。部分情况,可能是直接被拦截,都没有这个提示。

Windows 防火墙规则 | Microsoft Learn

如果出现问题,手动处理的话,可以在 Windows 防火墙的高级设置中,添加入站或出站规则,或者配置 “允许应用或功能通过 Windows Defender 防火墙”。

这里介绍的是,如果在应用安装时(使用 NSIS 打包),自动添加防火墙规则,避免上述问题。

netsh advfirewall

基本思路是使用 netsh advfirewall 命令来进行防火墙规则的添加,

添加规则命令参考:

netsh advfirewall firewall add rule name="ruleName" program="C:\Program Files\7-Zip\7z.exe" action=allow dir=in enable=yes

移除规则命令参考(卸载时调用):

netsh advfirewall firewall delete rule name="ruleName" 

关于 netsh advfirewall 的更多资料

Use netsh advfirewall firewall context - Windows Server | Microsoft Learn

在 NSIS 中集成上述 netsh 命令

在 NSIS 脚本中,可以通过 ExecWait 直接执行命令,参考如下

#define FIREWALL_NAME "my dicom viewer"

Function .onInstSuccess
  ExecWait 'netsh advfirewall firewall add rule name="${FIREWALL_NAME}" program="$INSTDIR\DicomViewer.exe" dir=in action=allow'
  ExecWait 'netsh advfirewall firewall add rule name="${FIREWALL_NAME}" program="$INSTDIR\DicomViewer.exe" dir=out action=allow'
FunctionEnd

Function un.onUninstSuccess
  ExecWait 'netsh advfirewall firewall delete rule name="${FIREWALL_NAME}"'
  HideWindow
  MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) 已成功地从您的计算机移除"
FunctionEnd

上述写法能成功执行,但是有个问题,在执行时,会打开 CMD 命令行窗口。看起来的效果就是会有黑框框一闪而过,如果是内部使用的工程板软件,勉强可以接受,如果是面向用户的软件,这个问题还需要进一步处理。

改进 CMD 命令行窗口的闪烁

这里使用的方式是,在 NSIS 中,调用 vbs 脚本,可以做到没有命令行窗口。

添加规则的脚本如下

Dim arg1
arg1 = WScript.Arguments(0)

Dim shell
Set shell = CreateObject("WScript.Shell")

Dim ruleName
ruleName = "my dicom viewer"

Dim command1
command1 = "netsh advfirewall firewall add rule name=""" & ruleName & """ program=""" & arg1 & """ action=allow dir=in enable=yes"
Dim command2
command2 = "netsh advfirewall firewall add rule name=""" & ruleName & """ program=""" & arg1 & """ action=allow dir=out enable=yes"

shell.Run command1, 0, True ' 0 表示静默,True 表示等待命令执行完成
shell.Run command2, 0, True

删除规则的脚本如下

Dim shell
Set shell = CreateObject("WScript.Shell")

Dim ruleName
ruleName = "my dicom viewer"

Dim command1
command1 = "netsh advfirewall firewall delete rule name=""" & ruleName & """ "

shell.Run command1, 0, True ' 0 表示静默,True 表示等待命令执行完成

因为要在安装或者卸载时调用,所以这个文件要被放到安装包中。

Section "MainSection" SEC01
  SetOutPath "$INSTDIR"
  SetOverwrite ifnewer
  File "Script\after-install.vbs"
  File "Script\after-uninstall.vbs"
SectionEnd

在安装成功之后调用

; 安装成功之后调用
Function .onInstSuccess
  ExecWait '"wscript.exe" "$INSTDIR\after-install.vbs" "$INSTDIR\DicomViewer.exe"'
FunctionEnd

在卸载删除全部文件之前调用。因为这里是调用安装目录下的文件,所以不能放在 Function un.onUninstSuccess 中处理,因为那时候,文件都已经被删除了,无法被调用。

Section Uninstall
  Delete "$INSTDIR\uninst.exe"
  Delete "$INSTDIR\DicomViewer.exe"

  ExecWait '"wscript.exe" "$INSTDIR\after-uninstall.vbs" '
  Delete "$INSTDIR\*.*"
  RMDir /r "$INSTDIR"
SectionEnd

注意事项

netsh advfirewall 命令操作,需要管理员权限。通常安装程序会以管理员身份运行,如果不是,则需要注意这个问题。

原文链接:https://www.cnblogs.com/jasongrass/p/18389183

posted @ 2024-08-30 18:09  J.晒太阳的猫  阅读(29)  评论(2编辑  收藏  举报