tauri-apps / tauri

Build smaller, faster, and more secure desktop applications with a web frontend.
https://tauri.app
Apache License 2.0
78.53k stars 2.33k forks source link

[bug]Error using example in nsis template field #9765

Closed dong0926 closed 2 weeks ago

dong0926 commented 2 weeks ago

Describe the bug

name = "tauri"
version = "1.6.5"

name = "tauri-build"
version = "1.5.2"

name = "tauri-codegen"
version = "1.4.3"

name = "tauri-macros"
version = "1.4.4"

name = "tauri-runtime"
version = "0.14.3"

https://tauri.app/v1/guides/building/windows/#customizing-the-nsis-installer-template

// tauri.config.json

"bundle": {
      "windows": {
        "nsis": {
          "template": "./builder/custom_builder.nsi"
        }
      }
   }

// ./builder/custom_builder.nsi

...The content is exactly the same as the example (https://github.com/tauri-apps/tauri/blob/tauri-v1.6.5/tooling/bundler/src/bundle/windows/templates/installer.nsi)
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("compression")], "compression")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("compression")], "compression")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("manufacturer")], "manufacturer")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("product_name")], "product_name")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("version")], "version")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("version_with_build")], "version_with_build")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("short_description")], "short_description")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("install_mode")], "install_mode")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("license")], "license")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("installer_icon")], "installer_icon")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("sidebar_image")], "sidebar_image")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("header_image")], "header_image")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("main_binary_name")], "main_binary_name")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("main_binary_path")], "main_binary_path")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("bundle_id")], "bundle_id")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("copyright")], "copyright")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("out_file")], "out_file")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("arch")], "arch")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("additional_plugins_path")], "additional_plugins_path")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("allow_downgrades")], "allow_downgrades")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("display_language_selector")], "display_language_selector")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("install_webview2_mode")], "install_webview2_mode")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("webview2_installer_args")], "webview2_installer_args")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("webview2_bootstrapper_path")], "webview2_bootstrapper_path")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("webview2_installer_path")], "webview2_installer_path")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("uninstaller_sign_cmd")], "uninstaller_sign_cmd")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("estimated_size")], "estimated_size")))
       Debug [handlebars::render] Rendering helper: "each", params: [PathAndJson { relative_path: Some("languages"), value: Context(Array [String("English")], ["languages"]) }], hash: {}
       Debug [handlebars::render] Rendering value: Path(Relative(([], "this")))
       Debug [handlebars::render] Rendering helper: "each", params: [PathAndJson { relative_path: Some("language_files"), value: Context(Array [String("English.nsh")], ["language_files"]) }], hash: {}
       Debug [handlebars::render] Rendering value: Path(Relative(([], "this")))
       Debug [handlebars::render] Rendering helper: "each", params: [PathAndJson { relative_path: Some("resources_dirs"), value: Missing }], hash: {}
       Debug [handlebars::render] Rendering helper: "each", params: [PathAndJson { relative_path: Some("resources"), value: Context(Object {"C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\cert\\cert.pem": Array [String("extends\\cert"), String("extends\\cert\\cert.pem")], "C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\cert\\identity.pfx": Array [String("extends\\cert"), String("extends\\cert\\identity.pfx")], "C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\cert\\key.pem": Array [String("extends\\cert"), String("extends\\cert\\key.pem")], "C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\resetDNS.bat": Array [String("extends"), String("extends\\resetDNS.bat")], "C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\resetNetwork.bat": Array [String("extends"), String("extends\\resetNetwork.bat")]}, ["resources"]) }], hash: {}
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("1")], "this.[1]")))
       Debug [handlebars::render] Rendering helper: "unescape-dollar-sign", params: [PathAndJson { relative_path: Some("@key"), value: Derived(String("C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\cert\\cert.pem")) }], hash: {}
       Error [tauri_cli_node] failed to bundle project: `Error rendering "installer.nsi" line 549, col 36: Helper not defined: "unescape-dollar-sign"`

Reproduction

No response

Expected behavior

No response

Full tauri info output

cross-env MYBUFF_APP_LOG="trace,hyper=info,reqwest=info" tauri "info"

[✔] Environment
    - OS: Windows 10.0.22631 X64
    ✔ WebView2: 124.0.2478.97
    ✔ MSVC: Visual Studio Community 2022
    ✔ rustc: 1.77.2 (25ef9e3d8 2024-04-09)
    ✔ Cargo: 1.77.2 (e52e36006 2024-03-26)
    ✔ rustup: 1.27.0 (bbb9276d2 2024-03-08)
    ✔ Rust toolchain: stable-x86_64-pc-windows-msvc (default)
    - node: 18.20.2
    - pnpm: 8.15.7
    - yarn: 1.22.22
    - npm: 10.5.0

[-] Packages
    - tauri [RUST]: 1.6.5
    - tauri-build [RUST]: 1.5.2
    - wry [RUST]: 0.24.9
    - tao [RUST]: 0.16.9
    - tauri-cli [RUST]: not installed!
    - @tauri-apps/api [NPM]: 1.0.0 (outdated, latest: 1.5.5)
    - @tauri-apps/cli [NPM]: 1.5.1 (outdated, latest: 1.5.13)

[-] App
    - build-type: bundle
    - CSP: default-src 'self'; img-src 'self' asset: https://asset.localhost
    - distDir: ../dist
    - devPath: http://localhost:8000/
    - framework: React
    - bundler: Vite

Stack trace

No response

Additional context

No response

FabianLars commented 2 weeks ago

You need to update @tauri-apps/cli to 1.5.13 for this template to work.

dong0926 commented 2 weeks ago

cross-env MYBUFF_APP_LOG="trace,hyper=info,reqwest=info" tauri "info"

[✔] Environment

[-] Packages

[-] App

You need to update @tauri-apps/cli to 1.5.13 for this template to work.

dong0926 commented 2 weeks ago

Still unable to build successfully

FabianLars commented 2 weeks ago

Exactly the same error? (please post it again just in case there are minor differences)

dong0926 commented 2 weeks ago
Copyright (c) .NET Foundation and contributors. All rights reserved.

main.wxs
     Running [tauri_bundler::bundle::windows::msi::wix] light to produce C:\Users\Administrator\Documents\codes\buff\mybuff-client\src-tauri\target\i686-pc-windows-msvc\release\bundle\msi\MyBuff_0.0.0_x86_en-US.msi
     Running [tauri_bundler::bundle::common] Command `C:\Users\Administrator\AppData\Local\tauri/WixTools\light.exe  -ext C:\Users\Administrator\AppData\Local\tauri/WixTools\WixUtilExtension.dll -ext C:\Users\Administrator\AppData\Local\tauri/WixTools\WixUIExtension.dll -o C:\Users\Administrator\Documents\codes\buff\mybuff-client\src-tauri\target\i686-pc-windows-msvc\release\wix\x86\output.msi -cultures:en-us -loc C:\Users\Administrator\Documents\codes\buff\mybuff-client\src-tauri\target\i686-pc-windows-msvc\release\wix\x86\locale.wxl *.wixobj`
Windows Installer XML Toolset Linker version 3.11.2.4516
Copyright (c) .NET Foundation and contributors. All rights reserved.

C:\Users\Administrator\Documents\codes\buff\mybuff-client\src-tauri\target\i686-pc-windows-msvc\release\wix\x86\main.wxs(189) : warning LGHT1076 : ICE03: String overflow (greater than length permitted in column); Table: CustomAction, Column: Target, Key(s): DownloadAndInvokeBootstrapper
C:\Users\Administrator\Documents\codes\buff\mybuff-client\src-tauri\target\i686-pc-windows-msvc\release\wix\x86\main.wxs(30) : warning LGHT1076 : ICE40: REINSTALLMODE is defined in the Property table. This may cause difficulties.
C:\Users\Administrator\Documents\codes\buff\mybuff-client\src-tauri\target\i686-pc-windows-msvc\release\wix\x86\main.wxs(107) : warning LGHT1076 : ICE57: Component 'CMP_UninstallShortcut' has both per-user and per-machine data with an HKCU Registry KeyPath.
C:\Users\Administrator\Documents\codes\buff\mybuff-client\src-tauri\target\i686-pc-windows-msvc\release\wix\x86\main.wxs(32) : warning LGHT1076 : ICE61: This product should remove only older versions of itself. No Maximum version was detected for the current product. (WIX_UPGRADE_DETECTED)
        Info [tauri_bundler::bundle::windows::nsis] Target: x86
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("compression")], "compression")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("compression")], "compression")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("manufacturer")], "manufacturer")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("product_name")], "product_name")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("version")], "version")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("version_with_build")], "version_with_build")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("short_description")], "short_description")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("install_mode")], "install_mode")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("license")], "license")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("installer_icon")], "installer_icon")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("sidebar_image")], "sidebar_image")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("header_image")], "header_image")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("main_binary_name")], "main_binary_name")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("main_binary_path")], "main_binary_path")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("bundle_id")], "bundle_id")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("copyright")], "copyright")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("out_file")], "out_file")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("arch")], "arch")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("additional_plugins_path")], "additional_plugins_path")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("allow_downgrades")], "allow_downgrades")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("display_language_selector")], "display_language_selector")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("install_webview2_mode")], "install_webview2_mode")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("webview2_installer_args")], "webview2_installer_args")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("webview2_bootstrapper_path")], "webview2_bootstrapper_path")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("webview2_installer_path")], "webview2_installer_path")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("uninstaller_sign_cmd")], "uninstaller_sign_cmd")))
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("estimated_size")], "estimated_size")))
       Debug [handlebars::render] Rendering helper: "each", params: [PathAndJson { relative_path: Some("languages"), value: Context(Array [String("English")], ["languages"]) }], hash: {}
       Debug [handlebars::render] Rendering value: Path(Relative(([], "this")))
       Debug [handlebars::render] Rendering helper: "each", params: [PathAndJson { relative_path: Some("language_files"), value: Context(Array [String("English.nsh")], ["language_files"]) }], hash: {}
       Debug [handlebars::render] Rendering value: Path(Relative(([], "this")))
       Debug [handlebars::render] Rendering helper: "each", params: [PathAndJson { relative_path: Some("resources_dirs"), value: Context(Array [String("extends"), String("extends\\cert")], ["resources_dirs"]) }], hash: {}
       Debug [handlebars::render] Rendering value: Path(Relative(([], "this")))
       Debug [handlebars::render] Rendering value: Path(Relative(([], "this")))
       Debug [handlebars::render] Rendering helper: "each", params: [PathAndJson { relative_path: Some("resources"), value: Context(Object {"C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\cert\\cert.pem": Array [String("extends\\cert"), String("extends\\cert\\cert.pem")], "C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\cert\\identity.pfx": Array [String("extends\\cert"), String("extends\\cert\\identity.pfx")], "C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\cert\\key.pem": Array [String("extends\\cert"), String("extends\\cert\\key.pem")], "C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\resetDNS.bat": Array [String("extends"), String("extends\\resetDNS.bat")], "C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\resetNetwork.bat": Array [String("extends"), String("extends\\resetNetwork.bat")]}, ["resources"]) }], hash: {}
       Debug [handlebars::render] Rendering value: Path(Relative(([Named("1")], "this.[1]")))
       Debug [handlebars::render] Rendering helper: "unescape-dollar-sign", params: [PathAndJson { relative_path: Some("@key"), value: Derived(String("C:\\Users\\Administrator\\Documents\\codes\\buff\\mybuff-client\\src-tauri\\extends\\cert\\cert.pem")) }], hash: {}
       Error [tauri_cli_node] failed to bundle project: `Error rendering "installer.nsi" line 549, col 36: Helper not defined: "unescape-dollar-sign"`
 ELIFECYCLE  Command failed with exit code 1.
FabianLars commented 2 weeks ago

can you check whether tauri --version also prints 1.5.13 ? It seems to work fine for me so i'm not sure what could be the issue here 🤔

Or maybe share the .nsi file? Maybe it got corrupted somehow.

dong0926 commented 2 weeks ago
PS C:\Users\Administrator\Documents\codes\buff\mybuff-client> pnpm tauri --version

> mybuff@0.0.0 tauri C:\Users\Administrator\Documents\codes\buff\mybuff-client
> cross-env MYBUFF_APP_LOG="trace,hyper=info,reqwest=info" tauri "--version"

tauri-cli 1.5.13

./builder/custom_builder.nsi
// ...The content is exactly the same as the example (https://github.com/tauri-apps/tauri/blob/tauri-v1.6.5/tooling/bundler/src/bundle/windows/templates/installer.nsi)

// Here are the details:

Unicode true
; Set the compression algorithm. Default is LZMA.
!if "{{compression}}" == ""
  SetCompressor /SOLID lzma
!else
  SetCompressor /SOLID "{{compression}}"
!endif

!include MUI2.nsh
!include FileFunc.nsh
!include x64.nsh
!include WordFunc.nsh
!include "StrFunc.nsh"
!include "Win\COM.nsh"
!include "Win\Propkey.nsh"
${StrCase}
${StrLoc}

!define MANUFACTURER "{{manufacturer}}"
!define PRODUCTNAME "{{product_name}}"
!define VERSION "{{version}}"
!define VERSIONWITHBUILD "{{version_with_build}}"
!define SHORTDESCRIPTION "{{short_description}}"
!define INSTALLMODE "{{install_mode}}"
!define LICENSE "{{license}}"
!define INSTALLERICON "{{installer_icon}}"
!define SIDEBARIMAGE "{{sidebar_image}}"
!define HEADERIMAGE "{{header_image}}"
!define MAINBINARYNAME "{{main_binary_name}}"
!define MAINBINARYSRCPATH "{{main_binary_path}}"
!define BUNDLEID "{{bundle_id}}"
!define COPYRIGHT "{{copyright}}"
!define OUTFILE "{{out_file}}"
!define ARCH "{{arch}}"
!define PLUGINSPATH "{{additional_plugins_path}}"
!define ALLOWDOWNGRADES "{{allow_downgrades}}"
!define DISPLAYLANGUAGESELECTOR "{{display_language_selector}}"
!define INSTALLWEBVIEW2MODE "{{install_webview2_mode}}"
!define WEBVIEW2INSTALLERARGS "{{webview2_installer_args}}"
!define WEBVIEW2BOOTSTRAPPERPATH "{{webview2_bootstrapper_path}}"
!define WEBVIEW2INSTALLERPATH "{{webview2_installer_path}}"
!define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCTNAME}"
!define MANUPRODUCTKEY "Software\${MANUFACTURER}\${PRODUCTNAME}"
!define UNINSTALLERSIGNCOMMAND "{{uninstaller_sign_cmd}}"
!define ESTIMATEDSIZE "{{estimated_size}}"

Name "${PRODUCTNAME}"
BrandingText "${COPYRIGHT}"
OutFile "${OUTFILE}"

VIProductVersion "${VERSIONWITHBUILD}"
VIAddVersionKey "ProductName" "${PRODUCTNAME}"
VIAddVersionKey "FileDescription" "${SHORTDESCRIPTION}"
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
VIAddVersionKey "FileVersion" "${VERSION}"
VIAddVersionKey "ProductVersion" "${VERSION}"

; Plugins path, currently exists for linux only
!if "${PLUGINSPATH}" != ""
    !addplugindir "${PLUGINSPATH}"
!endif

!if "${UNINSTALLERSIGNCOMMAND}" != ""
  !uninstfinalize '${UNINSTALLERSIGNCOMMAND}'
!endif

; Handle install mode, `perUser`, `perMachine` or `both`
!if "${INSTALLMODE}" == "perMachine"
  RequestExecutionLevel highest
!endif

!if "${INSTALLMODE}" == "currentUser"
  RequestExecutionLevel user
!endif

!if "${INSTALLMODE}" == "both"
  !define MULTIUSER_MUI
  !define MULTIUSER_INSTALLMODE_INSTDIR "${PRODUCTNAME}"
  !define MULTIUSER_INSTALLMODE_COMMANDLINE
  !if "${ARCH}" == "x64"
    !define MULTIUSER_USE_PROGRAMFILES64
  !else if "${ARCH}" == "arm64"
    !define MULTIUSER_USE_PROGRAMFILES64
  !endif
  !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${UNINSTKEY}"
  !define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "CurrentUser"
  !define MULTIUSER_INSTALLMODEPAGE_SHOWUSERNAME
  !define MULTIUSER_INSTALLMODE_FUNCTION RestorePreviousInstallLocation
  !define MULTIUSER_EXECUTIONLEVEL Highest
  !include MultiUser.nsh
!endif

; installer icon
!if "${INSTALLERICON}" != ""
  !define MUI_ICON "${INSTALLERICON}"
!endif

; installer sidebar image
!if "${SIDEBARIMAGE}" != ""
  !define MUI_WELCOMEFINISHPAGE_BITMAP "${SIDEBARIMAGE}"
!endif

; installer header image
!if "${HEADERIMAGE}" != ""
  !define MUI_HEADERIMAGE
  !define MUI_HEADERIMAGE_BITMAP  "${HEADERIMAGE}"
!endif

; Define registry key to store installer language
!define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
!define MUI_LANGDLL_REGISTRY_KEY "${MANUPRODUCTKEY}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"

; Installer pages, must be ordered as they appear
; 1. Welcome Page
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
!insertmacro MUI_PAGE_WELCOME

; 2. License Page (if defined)
!if "${LICENSE}" != ""
  !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
  !insertmacro MUI_PAGE_LICENSE "${LICENSE}"
!endif

; 3. Install mode (if it is set to `both`)
!if "${INSTALLMODE}" == "both"
  !define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
  !insertmacro MULTIUSER_PAGE_INSTALLMODE
!endif

; 4. Custom page to ask user if he wants to reinstall/uninstall
;    only if a previous installtion was detected
Var ReinstallPageCheck
Page custom PageReinstall PageLeaveReinstall
Function PageReinstall
  ; Uninstall previous WiX installation if exists.
  ;
  ; A WiX installer stores the isntallation info in registry
  ; using a UUID and so we have to loop through all keys under
  ; `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall`
  ; and check if `DisplayName` and `Publisher` keys match ${PRODUCTNAME} and ${MANUFACTURER}
  ;
  ; This has a potentional issue that there maybe another installation that matches
  ; our ${PRODUCTNAME} and ${MANUFACTURER} but wasn't installed by our WiX installer,
  ; however, this should be fine since the user will have to confirm the uninstallation
  ; and they can chose to abort it if doesn't make sense.
  StrCpy $0 0
  wix_loop:
    EnumRegKey $1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" $0
    StrCmp $1 "" wix_done ; Exit loop if there is no more keys to loop on
    IntOp $0 $0 + 1
    ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "DisplayName"
    ReadRegStr $R1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "Publisher"
    StrCmp "$R0$R1" "${PRODUCTNAME}${MANUFACTURER}" 0 wix_loop
    ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1" "UninstallString"
    ${StrCase} $R1 $R0 "L"
    ${StrLoc} $R0 $R1 "msiexec" ">"
    StrCmp $R0 0 0 wix_done
    StrCpy $R7 "wix"
    StrCpy $R6 "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$1"
    Goto compare_version
  wix_done:

  ; Check if there is an existing installation, if not, abort the reinstall page
  ReadRegStr $R0 SHCTX "${UNINSTKEY}" ""
  ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString"
  ${IfThen} "$R0$R1" == "" ${|} Abort ${|}

  ; Compare this installar version with the existing installation
  ; and modify the messages presented to the user accordingly
  compare_version:
  StrCpy $R4 "$(older)"
  ${If} $R7 == "wix"
    ReadRegStr $R0 HKLM "$R6" "DisplayVersion"
  ${Else}
    ReadRegStr $R0 SHCTX "${UNINSTKEY}" "DisplayVersion"
  ${EndIf}
  ${IfThen} $R0 == "" ${|} StrCpy $R4 "$(unknown)" ${|}

  nsis_tauri_utils::SemverCompare "${VERSION}" $R0
  Pop $R0
  ; Reinstalling the same version
  ${If} $R0 == 0
    StrCpy $R1 "$(alreadyInstalledLong)"
    StrCpy $R2 "$(addOrReinstall)"
    StrCpy $R3 "$(uninstallApp)"
    !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(chooseMaintenanceOption)"
    StrCpy $R5 "2"
  ; Upgrading
  ${ElseIf} $R0 == 1
    StrCpy $R1 "$(olderOrUnknownVersionInstalled)"
    StrCpy $R2 "$(uninstallBeforeInstalling)"
    StrCpy $R3 "$(dontUninstall)"
    !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)"
    StrCpy $R5 "1"
  ; Downgrading
  ${ElseIf} $R0 == -1
    StrCpy $R1 "$(newerVersionInstalled)"
    StrCpy $R2 "$(uninstallBeforeInstalling)"
    !if "${ALLOWDOWNGRADES}" == "true"
      StrCpy $R3 "$(dontUninstall)"
    !else
      StrCpy $R3 "$(dontUninstallDowngrade)"
    !endif
    !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)"
    StrCpy $R5 "1"
  ${Else}
    Abort
  ${EndIf}

  Call SkipIfPassive

  nsDialogs::Create 1018
  Pop $R4
  ${IfThen} $(^RTL) == 1 ${|} nsDialogs::SetRTL $(^RTL) ${|}

  ${NSD_CreateLabel} 0 0 100% 24u $R1
  Pop $R1

  ${NSD_CreateRadioButton} 30u 50u -30u 8u $R2
  Pop $R2
  ${NSD_OnClick} $R2 PageReinstallUpdateSelection

  ${NSD_CreateRadioButton} 30u 70u -30u 8u $R3
  Pop $R3
  ; disable this radio button if downgrading and downgrades are disabled
  !if "${ALLOWDOWNGRADES}" == "false"
    ${IfThen} $R0 == -1 ${|} EnableWindow $R3 0 ${|}
  !endif
  ${NSD_OnClick} $R3 PageReinstallUpdateSelection

  ; Check the first radio button if this the first time
  ; we enter this page or if the second button wasn't
  ; selected the last time we were on this page
  ${If} $ReinstallPageCheck != 2
    SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0
  ${Else}
    SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0
  ${EndIf}

  ${NSD_SetFocus} $R2
  nsDialogs::Show
FunctionEnd
Function PageReinstallUpdateSelection
  ${NSD_GetState} $R2 $R1
  ${If} $R1 == ${BST_CHECKED}
    StrCpy $ReinstallPageCheck 1
  ${Else}
    StrCpy $ReinstallPageCheck 2
  ${EndIf}
FunctionEnd
Function PageLeaveReinstall
  ${NSD_GetState} $R2 $R1

  ; $R5 holds whether we are reinstalling the same version or not
  ; $R5 == "1" -> different versions
  ; $R5 == "2" -> same version
  ;
  ; $R1 holds the radio buttons state. its meaning is dependant on the context
  StrCmp $R5 "1" 0 +2 ; Existing install is not the same version?
    StrCmp $R1 "1" reinst_uninstall reinst_done ; $R1 == "1", then user chose to uninstall existing version, otherwise skip uninstalling
  StrCmp $R1 "1" reinst_done ; Same version? skip uninstalling

  reinst_uninstall:
    HideWindow
    ClearErrors

    ${If} $R7 == "wix"
      ReadRegStr $R1 HKLM "$R6" "UninstallString"
      ExecWait '$R1' $0
    ${Else}
      ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" ""
      ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString"
      ExecWait '$R1 /P _?=$4' $0
    ${EndIf}

    BringToFront

    ${IfThen} ${Errors} ${|} StrCpy $0 2 ${|} ; ExecWait failed, set fake exit code

    ${If} $0 <> 0
    ${OrIf} ${FileExists} "$INSTDIR\${MAINBINARYNAME}.exe"
      ${If} $0 = 1 ; User aborted uninstaller?
        StrCmp $R5 "2" 0 +2 ; Is the existing install the same version?
          Quit ; ...yes, already installed, we are done
        Abort
      ${EndIf}
      MessageBox MB_ICONEXCLAMATION "$(unableToUninstall)"
      Abort
    ${Else}
      StrCpy $0 $R1 1
      ${IfThen} $0 == '"' ${|} StrCpy $R1 $R1 -1 1 ${|} ; Strip quotes from UninstallString
      Delete $R1
      RMDir $INSTDIR
    ${EndIf}
  reinst_done:
FunctionEnd

; 5. Choose install directoy page
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
!insertmacro MUI_PAGE_DIRECTORY

; 6. Start menu shortcut page
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
Var AppStartMenuFolder
!insertmacro MUI_PAGE_STARTMENU Application $AppStartMenuFolder

; 7. Installation page
!insertmacro MUI_PAGE_INSTFILES

; 8. Finish page
;
; Don't auto jump to finish page after installation page,
; because the installation page has useful info that can be used debug any issues with the installer.
!define MUI_FINISHPAGE_NOAUTOCLOSE
; Use show readme button in the finish page as a button create a desktop shortcut
!define MUI_FINISHPAGE_SHOWREADME
!define MUI_FINISHPAGE_SHOWREADME_TEXT "$(createDesktop)"
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateDesktopShortcut
; Show run app after installation.
!define MUI_FINISHPAGE_RUN "$INSTDIR\${MAINBINARYNAME}.exe"
!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
!insertmacro MUI_PAGE_FINISH

; Uninstaller Pages
; 1. Confirm uninstall page
Var DeleteAppDataCheckbox
Var DeleteAppDataCheckboxState
!define /ifndef WS_EX_LAYOUTRTL         0x00400000
!define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ConfirmShow
Function un.ConfirmShow
    FindWindow $1 "#32770" "" $HWNDPARENT ; Find inner dialog
    ${If} $(^RTL) == 1
      System::Call 'USER32::CreateWindowEx(i${__NSD_CheckBox_EXSTYLE}|${WS_EX_LAYOUTRTL},t"${__NSD_CheckBox_CLASS}",t "$(deleteAppData)",i${__NSD_CheckBox_STYLE},i 50,i 100,i 400, i 25,i$1,i0,i0,i0)i.s'
    ${Else}
      System::Call 'USER32::CreateWindowEx(i${__NSD_CheckBox_EXSTYLE},t"${__NSD_CheckBox_CLASS}",t "$(deleteAppData)",i${__NSD_CheckBox_STYLE},i 0,i 100,i 400, i 25,i$1,i0,i0,i0)i.s'
    ${EndIf}
    Pop $DeleteAppDataCheckbox
    SendMessage $HWNDPARENT ${WM_GETFONT} 0 0 $1
    SendMessage $DeleteAppDataCheckbox ${WM_SETFONT} $1 1
FunctionEnd
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.ConfirmLeave
Function un.ConfirmLeave
    SendMessage $DeleteAppDataCheckbox ${BM_GETCHECK} 0 0 $DeleteAppDataCheckboxState
FunctionEnd
!insertmacro MUI_UNPAGE_CONFIRM

; 2. Uninstalling Page
!insertmacro MUI_UNPAGE_INSTFILES

;Languages
{{#each languages}}
!insertmacro MUI_LANGUAGE "{{this}}"
{{/each}}
!insertmacro MUI_RESERVEFILE_LANGDLL
{{#each language_files}}
  !include "{{this}}"
{{/each}}

!macro SetContext
  !if "${INSTALLMODE}" == "currentUser"
    SetShellVarContext current
  !else if "${INSTALLMODE}" == "perMachine"
    SetShellVarContext all
  !endif

  ${If} ${RunningX64}
    !if "${ARCH}" == "x64"
      SetRegView 64
    !else if "${ARCH}" == "arm64"
      SetRegView 64
    !else
      SetRegView 32
    !endif
  ${EndIf}
!macroend

Var PassiveMode
Function .onInit
  ${GetOptions} $CMDLINE "/P" $PassiveMode
  IfErrors +2 0
    StrCpy $PassiveMode 1

  !if "${DISPLAYLANGUAGESELECTOR}" == "true"
    !insertmacro MUI_LANGDLL_DISPLAY
  !endif

  !insertmacro SetContext

  ${If} $INSTDIR == ""
    ; Set default install location
    !if "${INSTALLMODE}" == "perMachine"
      ${If} ${RunningX64}
        !if "${ARCH}" == "x64"
          StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCTNAME}"
        !else if "${ARCH}" == "arm64"
          StrCpy $INSTDIR "$PROGRAMFILES64\${PRODUCTNAME}"
        !else
          StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCTNAME}"
        !endif
      ${Else}
        StrCpy $INSTDIR "$PROGRAMFILES\${PRODUCTNAME}"
      ${EndIf}
    !else if "${INSTALLMODE}" == "currentUser"
      StrCpy $INSTDIR "$LOCALAPPDATA\${PRODUCTNAME}"
    !endif

    Call RestorePreviousInstallLocation
  ${EndIf}

  !if "${INSTALLMODE}" == "both"
    !insertmacro MULTIUSER_INIT
  !endif
FunctionEnd

Section EarlyChecks
  ; Abort silent installer if downgrades is disabled
  !if "${ALLOWDOWNGRADES}" == "false"
  IfSilent 0 silent_downgrades_done
    ; If downgrading
    ${If} $R0 == -1
      System::Call 'kernel32::AttachConsole(i -1)i.r0'
      ${If} $0 != 0
        System::Call 'kernel32::GetStdHandle(i -11)i.r0'
        System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color
        FileWrite $0 "$(silentDowngrades)"
      ${EndIf}
      Abort
    ${EndIf}
  silent_downgrades_done:
  !endif

SectionEnd

Section WebView2
  ; Check if Webview2 is already installed and skip this section
  ${If} ${RunningX64}
    ReadRegStr $4 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
  ${Else}
    ReadRegStr $4 HKLM "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
  ${EndIf}
  ReadRegStr $5 HKCU "SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"

  StrCmp $4 "" 0 webview2_done
  StrCmp $5 "" 0 webview2_done

  ; Webview2 install modes
  !if "${INSTALLWEBVIEW2MODE}" == "downloadBootstrapper"
    Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe"
    DetailPrint "$(webview2Downloading)"
    NSISdl::download "https://go.microsoft.com/fwlink/p/?LinkId=2124703" "$TEMP\MicrosoftEdgeWebview2Setup.exe"
    Pop $0
    ${If} $0 == 0
      DetailPrint "$(webview2DownloadSuccess)"
    ${Else}
      DetailPrint "$(webview2DownloadError)"
      Abort "$(webview2AbortError)"
    ${EndIf}
    StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe"
    Goto install_webview2
  !endif

  !if "${INSTALLWEBVIEW2MODE}" == "embedBootstrapper"
    Delete "$TEMP\MicrosoftEdgeWebview2Setup.exe"
    File "/oname=$TEMP\MicrosoftEdgeWebview2Setup.exe" "${WEBVIEW2BOOTSTRAPPERPATH}"
    DetailPrint "$(installingWebview2)"
    StrCpy $6 "$TEMP\MicrosoftEdgeWebview2Setup.exe"
    Goto install_webview2
  !endif

  !if "${INSTALLWEBVIEW2MODE}" == "offlineInstaller"
    Delete "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe"
    File "/oname=$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe" "${WEBVIEW2INSTALLERPATH}"
    DetailPrint "$(installingWebview2)"
    StrCpy $6 "$TEMP\MicrosoftEdgeWebView2RuntimeInstaller.exe"
    Goto install_webview2
  !endif

  Goto webview2_done

  install_webview2:
    DetailPrint "$(installingWebview2)"
    ; $6 holds the path to the webview2 installer
    ExecWait "$6 ${WEBVIEW2INSTALLERARGS} /install" $1
    ${If} $1 == 0
      DetailPrint "$(webview2InstallSuccess)"
    ${Else}
      DetailPrint "$(webview2InstallError)"
      Abort "$(webview2AbortError)"
    ${EndIf}
  webview2_done:
SectionEnd

!macro CheckIfAppIsRunning
  !if "${INSTALLMODE}" == "currentUser"
    nsis_tauri_utils::FindProcessCurrentUser "${MAINBINARYNAME}.exe"
  !else
    nsis_tauri_utils::FindProcess "${MAINBINARYNAME}.exe"
  !endif
  Pop $R0
  ${If} $R0 = 0
      IfSilent kill 0
      ${IfThen} $PassiveMode != 1 ${|} MessageBox MB_OKCANCEL "$(appRunningOkKill)" IDOK kill IDCANCEL cancel ${|}
      kill:
        !if "${INSTALLMODE}" == "currentUser"
          nsis_tauri_utils::KillProcessCurrentUser "${MAINBINARYNAME}.exe"
        !else
          nsis_tauri_utils::KillProcess "${MAINBINARYNAME}.exe"
        !endif
        Pop $R0
        Sleep 500
        ${If} $R0 = 0
          Goto app_check_done
        ${Else}
          IfSilent silent ui
          silent:
            System::Call 'kernel32::AttachConsole(i -1)i.r0'
            ${If} $0 != 0
              System::Call 'kernel32::GetStdHandle(i -11)i.r0'
              System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color
              FileWrite $0 "$(appRunning)$\n"
            ${EndIf}
            Abort
          ui:
            Abort "$(failedToKillApp)"
        ${EndIf}
      cancel:
        Abort "$(appRunning)"
  ${EndIf}
  app_check_done:
!macroend

Section Install
  SetOutPath $INSTDIR

  !insertmacro CheckIfAppIsRunning

  ; Copy main executable
  File "${MAINBINARYSRCPATH}"

  ; Copy resources
  {{#each resources_dirs}}
    CreateDirectory "$INSTDIR\\{{this}}"
  {{/each}}
  {{#each resources}}
    File /a "/oname={{this.[1]}}" "{{unescape-dollar-sign @key}}"
  {{/each}}

  ; Copy external binaries
  {{#each binaries}}
    File /a "/oname={{this}}" "{{unescape-dollar-sign @key}}"
  {{/each}}

  ; Create uninstaller
  WriteUninstaller "$INSTDIR\uninstall.exe"

  ; Save $INSTDIR in registry for future installations
  WriteRegStr SHCTX "${MANUPRODUCTKEY}" "" $INSTDIR

  !if "${INSTALLMODE}" == "both"
    ; Save install mode to be selected by default for the next installation such as updating
    ; or when uninstalling
    WriteRegStr SHCTX "${UNINSTKEY}" $MultiUser.InstallMode 1
  !endif

  ; Registry information for add/remove programs
  WriteRegStr SHCTX "${UNINSTKEY}" "DisplayName" "${PRODUCTNAME}"
  WriteRegStr SHCTX "${UNINSTKEY}" "DisplayIcon" "$\"$INSTDIR\${MAINBINARYNAME}.exe$\""
  WriteRegStr SHCTX "${UNINSTKEY}" "DisplayVersion" "${VERSION}"
  WriteRegStr SHCTX "${UNINSTKEY}" "Publisher" "${MANUFACTURER}"
  WriteRegStr SHCTX "${UNINSTKEY}" "InstallLocation" "$\"$INSTDIR$\""
  WriteRegStr SHCTX "${UNINSTKEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
  WriteRegDWORD SHCTX "${UNINSTKEY}" "NoModify" "1"
  WriteRegDWORD SHCTX "${UNINSTKEY}" "NoRepair" "1"
  WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "${ESTIMATEDSIZE}"

  ; Create start menu shortcut (GUI)
  !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
    Call CreateStartMenuShortcut
  !insertmacro MUI_STARTMENU_WRITE_END

  ; Create shortcuts for silent and passive installers, which
  ; can be disabled by passing `/NS` flag
  ; GUI installer has buttons for users to control creating them
  IfSilent check_ns_flag 0
  ${IfThen} $PassiveMode == 1 ${|} Goto check_ns_flag ${|}
  Goto shortcuts_done
  check_ns_flag:
    ${GetOptions} $CMDLINE "/NS" $R0
    IfErrors 0 shortcuts_done
      Call CreateDesktopShortcut
      Call CreateStartMenuShortcut
  shortcuts_done:

  ; Auto close this page for passive mode
  ${IfThen} $PassiveMode == 1 ${|} SetAutoClose true ${|}
SectionEnd

Function .onInstSuccess
  ; Check for `/R` flag only in silent and passive installers because
  ; GUI installer has a toggle for the user to (re)start the app
  IfSilent check_r_flag 0
  ${IfThen} $PassiveMode == 1 ${|} Goto check_r_flag ${|}
  Goto run_done
  check_r_flag:
    ${GetOptions} $CMDLINE "/R" $R0
    IfErrors run_done 0
      ${GetOptions} $CMDLINE "/ARGS" $R0
      Exec '"$INSTDIR\${MAINBINARYNAME}.exe" $R0'
  run_done:
FunctionEnd

Function un.onInit
  !insertmacro SetContext

  !if "${INSTALLMODE}" == "both"
    !insertmacro MULTIUSER_UNINIT
  !endif

  !insertmacro MUI_UNGETLANGUAGE
FunctionEnd

!macro DeleteAppUserModelId
  !insertmacro ComHlpr_CreateInProcInstance ${CLSID_DestinationList} ${IID_ICustomDestinationList} r1 ""
  ${If} $1 P<> 0
    ${ICustomDestinationList::DeleteList} $1 '("${BUNDLEID}")'
    ${IUnknown::Release} $1 ""
  ${EndIf}
  !insertmacro ComHlpr_CreateInProcInstance ${CLSID_ApplicationDestinations} ${IID_IApplicationDestinations} r1 ""
  ${If} $1 P<> 0
    ${IApplicationDestinations::SetAppID} $1 '("${BUNDLEID}")i.r0'
    ${If} $0 >= 0
      ${IApplicationDestinations::RemoveAllDestinations} $1 ''
    ${EndIf}
    ${IUnknown::Release} $1 ""
  ${EndIf}
!macroend

; From https://stackoverflow.com/a/42816728/16993372
!macro UnpinShortcut shortcut
  !insertmacro ComHlpr_CreateInProcInstance ${CLSID_StartMenuPin} ${IID_IStartMenuPinnedList} r0 ""
  ${If} $0 P<> 0
      System::Call 'SHELL32::SHCreateItemFromParsingName(ws, p0, g "${IID_IShellItem}", *p0r1)' "${shortcut}"
      ${If} $1 P<> 0
          ${IStartMenuPinnedList::RemoveFromList} $0 '(r1)'
          ${IUnknown::Release} $1 ""
      ${EndIf}
      ${IUnknown::Release} $0 ""
  ${EndIf}
!macroend

Section Uninstall
  !insertmacro CheckIfAppIsRunning

  ; Delete the app directory and its content from disk
  ; Copy main executable
  Delete "$INSTDIR\${MAINBINARYNAME}.exe"

  ; Delete resources
  {{#each resources}}
    Delete "$INSTDIR\\{{this.[1]}}"
  {{/each}}

  ; Delete external binaries
  {{#each binaries}}
    Delete "$INSTDIR\\{{this}}"
  {{/each}}

  ; Delete uninstaller
  Delete "$INSTDIR\uninstall.exe"

  {{#each resources_ancestors}}
  RMDir /REBOOTOK "$INSTDIR\\{{this}}"
  {{/each}}
  RMDir "$INSTDIR"

  !insertmacro DeleteAppUserModelId
  !insertmacro UnpinShortcut "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk"
  !insertmacro UnpinShortcut "$DESKTOP\${MAINBINARYNAME}.lnk"

  ; Remove start menu shortcut
  !insertmacro MUI_STARTMENU_GETFOLDER Application $AppStartMenuFolder
  Delete "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk"
  RMDir "$SMPROGRAMS\$AppStartMenuFolder"

  ; Remove desktop shortcuts
  Delete "$DESKTOP\${MAINBINARYNAME}.lnk"

  ; Remove registry information for add/remove programs
  !if "${INSTALLMODE}" == "both"
    DeleteRegKey SHCTX "${UNINSTKEY}"
  !else if "${INSTALLMODE}" == "perMachine"
    DeleteRegKey HKLM "${UNINSTKEY}"
  !else
    DeleteRegKey HKCU "${UNINSTKEY}"
  !endif

  DeleteRegValue HKCU "${MANUPRODUCTKEY}" "Installer Language"

  ; Delete app data
  ${If} $DeleteAppDataCheckboxState == 1
    SetShellVarContext current
    RmDir /r "$APPDATA\${BUNDLEID}"
    RmDir /r "$LOCALAPPDATA\${BUNDLEID}"
  ${EndIf}

  ${GetOptions} $CMDLINE "/P" $R0
  IfErrors +2 0
    SetAutoClose true
SectionEnd

Function RestorePreviousInstallLocation
  ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" ""
  StrCmp $4 "" +2 0
    StrCpy $INSTDIR $4
FunctionEnd

Function SkipIfPassive
  ${IfThen} $PassiveMode == 1  ${|} Abort ${|}
FunctionEnd

!macro SetLnkAppUserModelId shortcut
  !insertmacro ComHlpr_CreateInProcInstance ${CLSID_ShellLink} ${IID_IShellLink} r0 ""
  ${If} $0 P<> 0
    ${IUnknown::QueryInterface} $0 '("${IID_IPersistFile}",.r1)'
    ${If} $1 P<> 0
      ${IPersistFile::Load} $1 '("${shortcut}", ${STGM_READWRITE})'
      ${IUnknown::QueryInterface} $0 '("${IID_IPropertyStore}",.r2)'
      ${If} $2 P<> 0
        System::Call 'Oleaut32::SysAllocString(w "${BUNDLEID}") i.r3'
        System::Call '*${SYSSTRUCT_PROPERTYKEY}(${PKEY_AppUserModel_ID})p.r4'
        System::Call '*${SYSSTRUCT_PROPVARIANT}(${VT_BSTR},,&i4 $3)p.r5'
        ${IPropertyStore::SetValue} $2 '($4,$5)'

        System::Call 'Oleaut32::SysFreeString($3)'
        System::Free $4
        System::Free $5
        ${IPropertyStore::Commit} $2 ""
        ${IUnknown::Release} $2 ""
        ${IPersistFile::Save} $1 '("${shortcut}",1)'
      ${EndIf}
      ${IUnknown::Release} $1 ""
    ${EndIf}
    ${IUnknown::Release} $0 ""
  ${EndIf}
!macroend

Function CreateDesktopShortcut
  CreateShortcut "$DESKTOP\${MAINBINARYNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
  !insertmacro SetLnkAppUserModelId "$DESKTOP\${MAINBINARYNAME}.lnk"
FunctionEnd

Function CreateStartMenuShortcut
  CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder"
  CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
  !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk"
FunctionEnd
FabianLars commented 2 weeks ago

Hmm yeah, that's the same i tried. Last thing i can think of, can you delete the target folder so that the cache gets deleted?

dong0926 commented 2 weeks ago

Can you tell me exactly where and how to delete it

FabianLars commented 2 weeks ago

If your project via create-tauri-app or tauri init then it will be src-tauri/target/. You can just delete it, or move it to trash, like every other file. Alternatively, just run cargo clean inside src-tauri and cargo will delete it for you.

dong0926 commented 2 weeks ago

I tried, but I couldn't

dong0926 commented 2 weeks ago

@FabianLars Can you use it normally in this environment

amrbashir commented 2 weeks ago

you need to use 1.5.14 not 1.5.13 and seems like our CI failed to publish that version, I have triggered CI to publish it now, gonna take a few minutes.

amrbashir commented 2 weeks ago

It is published now

dong0926 commented 2 weeks ago

Hoo! thank u. This is my first time using tauri. The efficiency of the community surprised me.