前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >NSIS 脚本,安装时添加防火墙规则

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

作者头像
jgrass
发布2024-12-25 18:32:37
发布2024-12-25 18:32:37
7400
代码可运行
举报
文章被收录于专栏:蔻丁杂记蔻丁杂记
运行总次数:0
代码可运行

根据 lindexi 的建议,可以用如下更优的方案:

根据 C 厂的长期实践经验,最佳做法是写一个 UpdateFix 类似的程序集,

然后通过命令行参数调用起来,靠 C# 代码编写逻辑处理防火墙。

一方面可以实现较高控制,避免各种脚本的奇异表现和让杀毒软件开森,

另一方面可以比较方便编写代码进行调试以及在后续 OTA 时执行统一的行为

场景

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

Windows 防火墙规则 | Microsoft Learn

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

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

netsh advfirewall

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

添加规则命令参考:

Terminal window

代码语言:javascript
代码运行次数:0
复制
netsh advfirewall firewall add rule name="ruleName" program="C:\Program Files\7-Zip\7z.exe" action=allow dir=in enable=yes

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

Terminal window

代码语言:javascript
代码运行次数:0
复制
netsh advfirewall firewall delete rule name="ruleName"

关于 netsh advfirewall 的更多资料

Use netsh advfirewall firewall context - Windows Server | Microsoft Learn

在 NSIS 中集成上述 netsh 命令

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

代码语言:javascript
代码运行次数:0
复制
#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 脚本,可以做到没有命令行窗口。

添加规则的脚本如下

代码语言:javascript
代码运行次数:0
复制
Dim arg1arg1 = WScript.Arguments(0)
Dim shellSet shell = CreateObject("WScript.Shell")
Dim ruleNameruleName = "my dicom viewer"
Dim command1command1 = "netsh advfirewall firewall add rule name=""" & ruleName & """ program=""" & arg1 & """ action=allow dir=in enable=yes"Dim command2command2 = "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

删除规则的脚本如下

代码语言:javascript
代码运行次数:0
复制
Dim shellSet shell = CreateObject("WScript.Shell")
Dim ruleNameruleName = "my dicom viewer"
Dim command1command1 = "netsh advfirewall firewall delete rule name=""" & ruleName & """ "
shell.Run command1, 0, True ' 0 表示静默,True 表示等待命令执行完成

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

代码语言:javascript
代码运行次数:0
复制
Section "MainSection" SEC01  SetOutPath "$INSTDIR"  SetOverwrite ifnewer  File "Script\after-install.vbs"  File "Script\after-uninstall.vbs"SectionEnd

在安装成功之后调用

代码语言:javascript
代码运行次数:0
复制
; 安装成功之后调用Function .onInstSuccess  ExecWait '"wscript.exe" "$INSTDIR\after-install.vbs" "$INSTDIR\DicomViewer.exe"'FunctionEnd

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

代码语言:javascript
代码运行次数:0
复制
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://cloud.tencent.com/developer/article/2481579

本作品采用 「署名 4.0 国际」 许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024年8月30日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 场景
  • netsh advfirewall
  • 在 NSIS 中集成上述 netsh 命令
  • 改进 CMD 命令行窗口的闪烁
  • 注意事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档