通过NSIS制作Windows安装包

  • 一、功能描述

  1. 安装基础程序
  2. 安装插件/扩展文件
  3. 检测运行环境并自动下载和安装
  4. 识别32位系统和64位系统
  5. 安装前检测是否已经打开了安装程序,避免重复安装
  • 二、NSIS正文

/*
Setup
version: 1.2

使用说明:
  文件存放以及nsi路径可按照以下结构进行分布(相对路径),"nsi"、"安装包"可根据实际进行配置

#######################
-文件夹               #
--_ProgramEnv         #
---Image              #
---ProgramEnv         #
--安装包              #
--Setup_1.2_x64.nsi   #
--AQDAS7              #
---bin                #
----1.dll             #
----2.dll             #
----3.dll             #
----0.exe             #
#######################

更新说明:
v1.2 :
     *优化变量名,做成通用的脚本,使后续安装包制作时很少的修改就能快速完成
     
*/


/*
 引用头文件
*/
# 
!include "MUI.nsh"   # 界面MUI 1.67
!include "x64.nsh"   # 检测系统位数

/*
  可更改参数参数;

  注意:除此之外的地方谨慎修改
*/
#
# 安装包适用系统的位数
!define system_bit "x64"
# 资源引用路径
!define resource_path "C:\Users\Administrator\OneDrive\公司\安装包\_ProgramEnv"
# 待打包文件目录,绝对/相对路径
!define fileDirectory ".\AQDAS7"
# 安装包输出路径
!define packupDirectory "C:\Users\Administrator\OneDrive\公司\安装包\z_安装包"
# 产品名称
!define productName "空气质量数据采集传输软件"
# 产品版本名称
!define productVersion "7.1.54"
# 安装目录名称
!define installDirectory "AQDAS7"
# 进程名称
!define exeName "More.AQDAS.App.exe"
# 安装包名称
!define setup_name "More.AQDAS_V${PRODUCT_VERSION}_Setup_${system_bit}.exe"
#
# End


/*
  NSIS参数
*/
#
!define PRODUCT_NAME ${productName} 
!define PRODUCT_VERSION ${productVersion}
#!define PRODUCT_VERSION_number "70151"
!define PRODUCT_PUBLISHER "上海xx科技有限公司"
!define PRODUCT_WEB_SITE "http://www.xxxxxx.com/"
!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\${exeName}"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
# HKLM 写成 HKEY_LOCAL_MACHINE 也可以
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
#
# End


/*
  安装界面
*/
#
# 图标
!define MUI_ABORTWARNING
!define MUI_ICON "${resource_path}\Image\logo_AQDAS\logo.ico"
!define MUI_UNICON "${resource_path}\Image\logo_AQDAS\uninstall.ico"
!define MUI_WELCOMEFINISHPAGE_BITMAP "${resource_path}\Image\logo_AQDAS\logo.bmp"
#
# 欢迎界面
!insertmacro MUI_PAGE_WELCOME
#
# 授权信息
#!insertmacro MUI_PAGE_LICENSE "授权文件.txt"
#
#选择安装文件夹界面
!insertmacro MUI_PAGE_DIRECTORY
#
# 选择组件页
!insertmacro MUI_PAGE_COMPONENTS
#
# 安装
!insertmacro MUI_PAGE_INSTFILES
#
# 安装完成后运行(需勾选)
!define MUI_FINISHPAGE_RUN "$INSTDIR\${installDirectory}\bin\${exeName}"
!insertmacro MUI_PAGE_FINISH
#
# 卸载界面
!insertmacro MUI_UNPAGE_INSTFILES
#
# 安装程序语言,放置多个则选择多语言
!insertmacro MUI_LANGUAGE "SimpChinese"
#
# 定义左下角文字
BrandingText ${PRODUCT_PUBLISHER}
#
# End


/*
  安装包文件信息
*/
# 
VIProductVersion "${PRODUCT_VERSION}.0" ;版本号,格式必须为 X.X.X.X (若使用则本条必须)
VIAddVersionKey  /LANG=${LANG_SimpChinese} "FileDescription" "${setup_name}" ;文件说明
VIAddVersionKey  /LANG=${LANG_SimpChinese} "ProductName" "${setup_name}" ;产品名称
VIAddVersionKey  /LANG=${LANG_SimpChinese} "CompanyName" "${PRODUCT_PUBLISHER}" ;公司名称
VIAddVersionKey  /LANG=${LANG_SimpChinese} "ProductVersion" "${PRODUCT_VERSION}" ;产品版本
VIAddVersionKey  /LANG=${LANG_SimpChinese} "LegalCopyright" ${productName} ;版权
#VIAddVersionKey  /LANG=${LANG_SimpChinese} "" ;商标
VIAddVersionKey  /LANG=${LANG_SimpChinese} "FileVersion" "${PRODUCT_VERSION}" ;文件版本
#
# End

/*
  其他
*/
# 安装程序标题、注册表软件标题
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
#
# 安装包输出路径
OutFile "${packupDirectory}/${setup_name}"
#
# 默认安装路径
# %文件名称%  :找寻系统盘下面的该目录
InstallDir "$PROGRAMFILES\MoreTech"
#
# 扫描注册表上次安装的位置,如果已安装则安装到安装到扫描到的路径,没有安装则安装到默认路径
#InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
ShowInstDetails hide
ShowUnInstDetails hide
#
# End


/*
  安装主程序
*/
#
# 
Section "-MainSection" SEC01
  # 安装位置
  SetOutPath "$INSTDIR"
  # try--相同文件则自动覆盖,若文件不可写入则忽略
  SetOverwrite try
  # 主程序文件
  File /r /x "Plugin" ${fileDirectory}
  SetOutPath "$INSTDIR\${installDirectory}"
  # 创建开始菜单目录
  CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
  # 创建开始菜单快捷方式
  CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\${installDirectory}\uninstall.exe"
  CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}v${PRODUCT_VERSION}.lnk" "$INSTDIR\${installDirectory}\bin\${exeName}"
  # 桌面快捷方式,目标位置
  CreateShortCut "$DESKTOP\${PRODUCT_NAME}v${PRODUCT_VERSION}.lnk" "$INSTDIR\${installDirectory}\bin\${exeName}"
SectionEnd
#
# End


/*
  安装插件
*/
#
Section /o "GMP343" SEC02
  SetOutPath "$INSTDIR\${installDirectory}\bin\Plugin"
  File /r "${fileDirectory}\bin\Plugin\GMP343_Plugin.dll"
SectionEnd
#
Section /o "温室气体质控" SEC03
  SetOutPath "$INSTDIR\${installDirectory}\bin\Plugin"
  File /r "${fileDirectory}\bin\Plugin\GreenhouseGas.dll"
SectionEnd
#
# 插件描述
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "主程序"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "VaisalaGMP343设备相关插件。$\r针对GPM343有以下功能$\r$\r1.写入湿度、压力数据。$\r2.串口调试。$\r3.校准。"
!insertmacro MUI_DESCRIPTION_TEXT ${SEC03} "温室气体相关插件。$\r对温室气体设备进行质控,并上传质控数据。"
!insertmacro MUI_FUNCTION_DESCRIPTION_END


/*
  注册表操作
*/
#
# 写入注册表
Section -Post
  # 卸载exe存放的位置
  WriteUninstaller "$INSTDIR\${installDirectory}\uninstall.exe"
  # App Paths
  WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\${installDirectory}\bin\${exeName}"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\${installDirectory}\uninstall.exe"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\${installDirectory}\bin\${exeName}"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
  #WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersionNumber" "${PRODUCT_VERSION_number}"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
  WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}"
  # 设置开机自启
  WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "${exeName}" "$INSTDIR\${installDirectory}\bin\${exeName}"
SectionEnd


/*
  卸载
*/
#
Section Uninstall
  # 删除桌面快捷方式
  Delete "$DESKTOP\${PRODUCT_NAME}v${PRODUCT_VERSION}.lnk"
  # 删除开始菜单中的快捷方式
  #Delete "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}v${PRODUCT_VERSION}.lnk"
  # 删除开始菜单中的文件夹
  RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
  /**
  # 删除安装目录中的文件
  Delete "$INSTDIR\bin\*.pdb"
  # 删除安装目录中的文件夹,/r递归删除
  RMDir /r "$INSTDIR\bin\zh-Hant"
  **/
  # 删除整个创建的文件夹,$INSTDIR 与 SetOutPath 相关,慎重使用 /r
  # REBOOTOK 被占用的文件重启后删除
  RMDir /r "$INSTDIR"
  #
  # 删除注册表
  DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
  DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
  #
  # 开机项
  DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" ${installDirectory}
  # 用于删除老版本的开机启动项
  DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "aqdas7Start"
  SetAutoClose true
SectionEnd


/*
  环境检测
*/
#
# 检测并安装vc++
Function detecd_vc
  # 定义vc下载链接
  Var /global vc2015_download_url
  
  # 定义下载后保存的文件名称
  Var /global vc2015_setup_name

  # 定义注册表路径
  Var /global vc2015_installed

  ${If} ${RunningX64}  # 需要头文件 "x64.nsh",若当前系统为x64位,则返回True
    # 获取键值, Installed为1时表示已安装,0表示未安装,32位和64位读取位置有所区别
    ReadRegStr $vc2015_installed HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64" "Installed"
    StrCpy $vc2015_download_url "https://download.microsoft.com/download/6/D/F/6DF3FF94-F7F9-4F0B-838C-A328D1A7D0EE/vc_redist.x64.exe"
    StrCpy $vc2015_setup_name "vc_redist.x64.exe"
  ${Else}
    ReadRegStr $vc2015_installed HKLM "SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86" "Installed"
    StrCpy $vc2015_download_url "https://download.microsoft.com/download/6/D/F/6DF3FF94-F7F9-4F0B-838C-A328D1A7D0EE/vc_redist.x86.exe"
    StrCpy $vc2015_setup_name "vc_redist.x86.exe"
  ${EndIf}

  # 只有 vc2015_installed为 1 时才表示已经安装
  ${If} $vc2015_installed != 1
    #MessageBox MB_OK "vc++没有安装,下面进行安装"
    inetc::get /WEAKSECURITY /CAPTION "$(^Name) 安装" /BANNER "$\r正在下载必要运行环境[Microsoft Visual C++2015]..." "$vc2015_download_url" \
             "$TEMP\$vc2015_setup_name" /END
    Pop $0
    StrCmp $0 "OK" dlok
    MessageBox MB_OK|MB_ICONEXCLAMATION "下载不成功,退出安装,检查网络环境后重试!若还是下载失败,请安装KB2999226补丁" /SD IDOK
      Abort
    dlok:
      ExecWait "$TEMP\$vc2015_setup_name /passive" $0
      # 返回值$0:0安装完成;1602安装被主动取消;1638已存在2015及以上版本vc++环境;其他返回值参考官网
      ${If} $0 = 0
        #MessageBox MB_OK "vc++2015已安装"
        Nop
      ${ElseIf} $0 = 1602
        MessageBox MB_OK|MB_ICONEXCLAMATION "状态代码:$0$\r Microsoft Visual C++2015安装失败,请重试。原因:主动取消安装。"
        Abort
      ${ElseIf} $0 = 3010
        MessageBox MB_OK|MB_ICONEXCLAMATION "状态代码:$0$\r Microsoft Visual C++2015安装完成,重启计算机后生效。"
      ${ElseIf} $0 = 1638
        MessageBox MB_OK|MB_ICONEXCLAMATION "状态代码:$0$\r Microsoft Visual C++2015及以上版本已存在与您的计算机中,可忽略上一步的错误,并向技术人员反馈您的计算机系统版本信息。"
      ${Else}
        MessageBox MB_OK|MB_ICONEXCLAMATION "状态代码:$0$\r Microsoft Visual C++2015安装失败,请重启计算机后重试。若重试仍旧无法正常安装,请截图该错误代码并报告技术人员。"
        Abort
      ${EndIf}
  ${EndIf}
    #MessageBox MB_OK "vc++环境已安装"
FunctionEnd
#
# 检测并安装windowsdesktopruntime
Function detecd_windowsdesktopruntime
  # 注意事项
  # 这个运行时的注册表路径目前只找到这一个地方,会有问题,不同的版本{...}中的值不一样
  # 目前检测的是6.0.4版本,如果安装的版本不是6.0.4,大于或者小于都无法检测出来

  # 定义注册表路径
  Var /global windowsdesktopruntime_reg_path_1
  Var /global windowsdesktopruntime_reg_path_2

  # 定义下载url
  Var /global wdr_download_url

  ${If} ${RunningX64}
    # x64路径
                                 #HKLM
    StrCpy $windowsdesktopruntime_reg_path_1 "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{73e5de3a-8f61-4a4a-ac84-0d7d5c9b9b5f}"
                                #HKLM
    # 这里是为了检测windowsdesktopruntime_v6.0.5,有一台客户装的是这个版本
    StrCpy $windowsdesktopruntime_reg_path_2 "SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{0f711ee3-eb88-456d-acb4-c2ee31add211}"

    StrCpy $wdr_download_url "https://download.visualstudio.microsoft.com/download/pr/f13d7b5c-608f-432b-b7ec-8fe84f4030a1/5e06998f9ce23c620b9d6bac2dae6c1d/windowsdesktop-runtime-6.0.4-win-x64.exe"

  ${Else}
    # x86路径
                                #HKLM
    StrCpy $windowsdesktopruntime_reg_path_1 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{ff0d7b6b-8624-42f0-b961-69e6cbf896c1}"
                                #HKLM
    StrCpy $windowsdesktopruntime_reg_path_2 "Nop"

    StrCpy $wdr_download_url "https://download.visualstudio.microsoft.com/download/pr/05b30243-5cd2-48c3-a9bb-6ac83d7d481b/03a25aecb5cf4ba53c8b9cf5194e3c86/windowsdesktop-runtime-6.0.4-win-x86.exe"
  ${EndIf}

  StrCpy $0 0
  ClearErrors  # 清除错误标记,这里清除$0的错误标记
  EnumRegValue $R0 HKLM "$windowsdesktopruntime_reg_path_1" $0
  IfErrors done  # 错误时跳转
  IntOp $0 $0 + 1  # 自加1
  done:
    StrCpy $1 0
    ClearErrors
    EnumRegValue $R1 HKCU "$windowsdesktopruntime_reg_path_2" $1
    IfErrors done_1
    IntOp $1 $1 + 1
    done_1:
      # 返回值-->$0 $1
      # 1代表键存在
      # 0代表键不存在
      ${If} $0 = 1
      ${OrIf} $1 = 1
        #MessageBox MB_OK "windowsdesktopruntime已安装"
        Nop
      ${Else}
        #Nop
        #MessageBox MB_OK "windowsdesktopruntime未安装"
        inetc::get /WEAKSECURITY /CAPTION "$(^Name) 安装" /BANNER "$\r正在下载必要运行环境[Microsoft Windows Desktop Runtime]..." "$wdr_download_url" \
             "$TEMP\windowsdesktopruntimesetup.exe"
        Pop $0
        StrCmp $0 "OK" dlok
        MessageBox MB_OK|MB_ICONEXCLAMATION "Microsoft Windows Desktop Runtime下载不成功,退出安装,检查网络环境后重试!" /SD IDOK
        Abort
        dlok:
          #ExecWait "$TEMP\windowsdesktopruntimesetup.exe /install /quiet /norestart" $0
          ExecWait "$TEMP\windowsdesktopruntimesetup.exe /passive" $0
          ${If} $0 = 0
            #MessageBox MB_OK "windowsdesktopruntime安装成功。"
            Nop
          ${ElseIf} $0 = 1602
            MessageBox MB_OK "状态代码:$0$\r安装失败,点击确定后退出"
            Abort
          ${Else}
            MessageBox MB_OK "状态代码:$0$\r Microsoft Windows Desktop Runtime安装失败,请重试!若重试仍旧无法正常安装,请截图该错误代码并报告技术人员。"
            Abort
          ${EndIf}
      ${EndIf}
FunctionEnd
#
# 检测并安装aspnetcore_runtime(兼容win7)
Function win7_detecd_aspnetcore_runtime
  # 注意事项,仅针对win7
  # 这个运行时的注册表路径目前只能用这一个地方,会有问题,不同的版本{...}中的值不一样
  # 目前检测的是6.0.4版本,如果安装的版本不是6.0.4/6.0.5,大于或者小于都无法检测出来


  # 定义注册表路径
  Var /global win7_aspnetcore_runtime_reg_path
  Var /global win7_aspnetcore_runtime_reg_path_1

  # 定义下载url及环境包名称
  Var /global win7_anr_download_url
  Var /global win7_download_setup_name

  ${If} ${RunningX64}
  #messageBox MB_OK "进入了系统位数检测,x64"
    # x64路径
                                 #HKLM,win7&win10相同
    StrCpy $win7_aspnetcore_runtime_reg_path "SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{de7bad2b-ba75-42bf-8c43-53c5d67efd01}"
                                #HKLM
    # 这里是为了检测windowsdesktopruntime_v6.0.5,有一台客户装的是这个版本
    StrCpy $win7_aspnetcore_runtime_reg_path_1 "SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{675e1f06-4fbf-4cfb-8554-d6dfee7a3a0a}"

    StrCpy $win7_anr_download_url "https://download.visualstudio.microsoft.com/download/pr/2162932c-987a-4de8-ae2a-f7d327bb39a8/97fe1cb950c2bccf44b7c3fe6aa45b53/aspnetcore-runtime-6.0.4-win-x64.exe"
    StrCpy $win7_download_setup_name "aspnetcoreruntime_6.0.4_x64.exe"

  ${Else}
    # x86路径
    #HKLM
    StrCpy $win7_aspnetcore_runtime_reg_path "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{07F565B3-B4AB-3912-BD14-61D32EF20FD1}"
    #HKLM
    StrCpy $win7_aspnetcore_runtime_reg_path_1 "Nop"

    StrCpy $win7_anr_download_url "https://download.visualstudio.microsoft.com/download/pr/c2093d31-b27e-4876-891c-750247cf1faa/33b9191b128a1d33671549972403994e/aspnetcore-runtime-6.0.4-win-x86.exe"
    StrCpy $win7_download_setup_name "aspnetcoreruntime_6.0.4_x86.exe"
  ${EndIf}

  StrCpy $0 0
  ClearErrors  # 清除错误标记,这里清除$0的错误标记
  EnumRegValue $R0 HKLM "$win7_aspnetcore_runtime_reg_path" $0
  IfErrors done  # 错误时跳转
  IntOp $0 $0 + 1  # 自加1
  done:
    StrCpy $1 0
    ClearErrors
    EnumRegValue $R1 HKLM "$win7_aspnetcore_runtime_reg_path_1" $1
    IfErrors done_1
    IntOp $1 $1 + 1
    done_1:
      # 返回值$0和$1-->1键存在;0键不存在
      ${If} $0 = 1
      ${OrIf} $1 = 1
        #MessageBox MB_OK "0-->$0,,1-->$1"
        #MessageBox MB_OK "aspnetcore_runtime已安装"
        Nop
      ${Else}
        #MessageBox MB_OK "0-->$0,,1-->$1"
        #MessageBox MB_OK "aspnetcore_runtime未安装"
        inetc::get /WEAKSECURITY /CAPTION "$(^Name) 安装" /BANNER "$\r正在下载必要运行环境[Microsoft Asp.Net Core]..." "$win7_anr_download_url" \
                 "$TEMP\$win7_download_setup_name" /END
        Pop $0
        StrCmp $0 "OK" dlok
        MessageBox MB_OK|MB_ICONEXCLAMATION "Microsoft Asp.Net Core下载不成功,退出安装。若网络环境正常,则请检查windows系统日志。" /SD IDOK
        Abort
        dlok:
          ExecWait "$TEMP\$win7_download_setup_name /passive" $0
          ${If} $0 = 0
            #MessageBox MB_OK "aspnetcore安装成功"
            Nop
          ${ElseIf} $0 = 1602
            MessageBox MB_OK "状态代码:$0$\r Microsoft Asp.Net Core安装失败,点击确定后退出"
            Abort
          ${Else}
            MessageBox MB_OK "状态代码:$0$\r Microsoft Asp.Net Core安装失败,请重试!若重试仍旧无法正常安装,请截图该错误代码并报告技术人员。"
            Abort
          ${EndIf}
      ${EndIf}
FunctionEnd
#
# 检测并安装webview2(在线下载版)
Function detecd_webview2
  # 注意事项
  # 这个运行时官方只给出了一个路径,可能会有问题,不同的版本{...}中的值不一样
  # 虽然目前官方只有这一个版本,但是不排除将来有可能改变
  # 如果发生改变,需要修改注册表路径,或者继续增加一个path_3的变量

  Var /global webview2_reg_path_1
  Var /global webview2_reg_path_2
  Var /global webview2_download_url
  Var /global webview2_download_setup_name

  ${If} ${RunningX64}
    # x64路径
                                 #HKLM
    StrCpy $webview2_reg_path_1 "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"
                                #HKCU
    StrCpy $webview2_reg_path_2 "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"

    StrCpy $webview2_download_url "https://go.microsoft.com/fwlink/p/?LinkId=2124703"
    StrCpy $webview2_download_setup_name "webview2setup_x64.exe"

  ${Else}
    # x86路径
                                #HKLM
    StrCpy $webview2_reg_path_1 "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"
                                #HKCU
    StrCpy $webview2_reg_path_2 "Software\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}"

    StrCpy $webview2_download_url "https://go.microsoft.com/fwlink/p/?LinkId=2124703"
    StrCpy $webview2_download_setup_name "webview2setup_x86.exe"
  ${EndIf}

  StrCpy $0 0
  ClearErrors  # 清除错误标记,这里清除$0的错误标记
  EnumRegValue $R0 HKLM "$webview2_reg_path_1" $0
  IfErrors done  # 错误时跳转
  IntOp $0 $0 + 1  # 自加1
  done:
    StrCpy $1 0
    ClearErrors
    EnumRegValue $R1 HKCU "$webview2_reg_path_2" $1
    IfErrors done_1
    IntOp $1 $1 + 1
    done_1:
      ${If} $0 = 1
      ${OrIf} $1 = 1
        #MessageBox MB_OK "webview2已安装"
        Nop
      ${Else}
        #Nop
        #MessageBox MB_OK "webview2未安装"
        inetc::get /WEAKSECURITY \
                   /RESUME "Internet 连接似乎已断开!$\n请单击重试接上次进度继续下载..." \
                   /CAPTION "$(^Name) 安装" \
                   /BANNER "$\r正在下载必要运行环境[webview2] ,请稍候..." "$webview2_download_url" "$TEMP\$webview2_download_setup_name" /END
        Pop $0
        StrCmp $0 "OK" dlok
        MessageBox MB_OK|MB_ICONEXCLAMATION "webview2下载不成功,退出安装,检查网络环境后重试!" /SD IDOK
          Abort
        dlok:
          ExecWait "$TEMP\$webview2_download_setup_name" $0
          ${If} $0 = 0
            Nop
          ${Else}
            MessageBox MB_OK "状态代码:$0$\r webview2安装失败,请重试!若重试仍旧无法正常安装,请截图该错误代码并报告技术人员。"
            Abort
          ${EndIf}
      ${EndIf}
FunctionEnd


/*
  前置动作
*/
#
# 安装之前运行
Function .onInit
  MessageBox MB_YESNO|MB_ICONQUESTION "是否开始安装${PRODUCT_NAME} v${PRODUCT_VERSION}?" IDYES gogogo_start_setup
    Abort
  gogogo_start_setup:
    Nop

  # 解压临时文件到 Temp 目录
  #InitPluginsDir
  #SetOutPath $PLUGINSDIR
  #File /nonfatal "${resource_path}\WebView2RuntimeInstaller_${system_bit}.exe"
  #ExecWait "$PLUGINSDIR/WebView2RuntimeInstaller_x64.exe"

  # 检测系统位数是否与安装包一致
  ${If} ${RunningX64}
    Nop
  ${Else}
    MessageBox MB_OK|MB_ICONEXCLAMATION "这是一个64位的程序,不适用于您的计算机!"
    Abort
  ${EndIf}
    
  # 禁止多个安装程序同时运行
  System::Call 'kernel32::CreateMutexA(i 0, i 0, t "myMutex") i .r1 ?e'
  Pop $R0
  StrCmp $R0 0 +3
    MessageBox MB_OK|MB_ICONEXCLAMATION "安装正在进行中,请勿重复运行!"
    Abort
    
  # 检测是否已安装程序
  ReadRegStr $3 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString"
  ${If} $3 != ""
    MessageBox MB_YESNO "检测到已经安装[ $3 ],请使用升级程序进行升级。若强行安装将会导致已有数据丢失,是否继续?" IDYES gogogo_1
    Abort
    gogogo_1:
      Nop
  ${EndIf}

  # 进程管理
  #
  # 关闭看门狗
  nsProcess::_KillProcess "More.WatchDog.exe"
  # 检测程序是否在运行,正在运行的话将其kill
  StrCpy $1 "${exeName}"
  nsProcess::_FindProcess "$1"
  Pop $R0
  ${If} $R0 = 0
    MessageBox MB_YESNO "安装程序检测到 $1 正在运行,是否强行关闭并继续安装?" IDYES gogogo
    Abort
    gogogo:
      nsProcess::_KillProcess "$1"
    Pop $R0
    Sleep 500
  ${EndIf}
  
  # 检测vc++环境
  Call detecd_vc
  #
  # 检测windowsdesktopruntime函数
  Call detecd_windowsdesktopruntime
  #
  # 检测aspnetcore_runtime
  Call win7_detecd_aspnetcore_runtime
  #
  # 检测webview2(在线安装)
  call detecd_webview2
  #
  # 检测webview2(离线安装)
  #Call detecd_webview2_1
  /*
  # 检测aspnetcore_runtime
  var /global isWindows7
  Version::IsWindows7  # 检测系统,需要用到version插件
  Pop $isWindows7
  ${if} $isWindows7 = 1
    #messageBox MB_OK "走的是win7函数"
    # 解决win7无法检测到Aspnetcoreruntime注册表路径的问题
    call win7_detecd_aspnetcore_runtime
  ${Else}
    call detecd_aspnetcore_runtime
  ${EndIf}
  */
FunctionEnd
#
# 安装完成后运行
Function .onInstSuccess
  Nop
FunctionEnd
#
# 卸载之前运行
Function un.onInit
  # 检测进程
  StrCpy $1 "${exeName}"
  nsProcess::_FindProcess "$1"
  Pop $R0
  ${If} $R0 = 0
    MessageBox MB_YESNO "卸载程序检测到 $1 正在运行,是否强行关闭?" IDYES gogogo
    Abort
    gogogo:
      nsProcess::_KillProcess "$1"
      nsProcess::_KillProcess "More.WatchDog.exe"
    Pop $R0
    Sleep 500
  ${EndIf}
  MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "你确实要完全移除 ${PRODUCT_NAME} ${PRODUCT_VERSION} ,其及所有的组件?" IDYES +2
  Abort
FunctionEnd
#
# 卸载完成后运行
Function un.onUninstSuccess
  HideWindow
  MessageBox MB_ICONINFORMATION|MB_OK "${PRODUCT_NAME} ${PRODUCT_VERSION} 已成功地从你的计算机移除。"
FunctionEnd
  • 三、补充说明

  1. 在有的win7上安装时,webviewer2有时候会出现无法下载、安装失败的问题,可能系统太老了,哪里有点什么问题,需要到官网手动下载安装。如果想安装失败继续安装的话,自行把失败提示下面的Abort删掉即可
  2. 可以在这个基础上制作升级包,去掉环境检测,注册表写入,卸载等操作即可
  3. 觉得描述不清晰不太理解、相了解更多写法可参考文末官方手册。

NSIS官方手册

NSIS插件中心

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值