Skip to content

Commit

Permalink
refactor(nsis): use nsis's built-in com plugin instead of Application…
Browse files Browse the repository at this point in the history
…ID plugin (#9606)

* Use WinShell instead of ApplicationID

* Uninst shortcut before removing start menu one

* Use nsis's buit-in com plugin instead of WinShell

* Remove download ApplicationID code

* Add change file

* Clippy and format

* Allow dead code on extract_zip

* Qualify extract_zip path to make clippy happy

* Move macro up

Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>
  • Loading branch information
amrbashir and Legend-Master committed Apr 30, 2024
1 parent 0749a84 commit b8fd8e1
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 23 deletions.
5 changes: 5 additions & 0 deletions .changes/drop-nsis-applicationid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri-bundler': 'patch:enhance'
---

Use nsis's built-in COM plugin instead of `ApplicationID` plugin, this reduces the installer size by 100 KB, and also fixes pinned shortcut not getting cleaned up on uninstall.
25 changes: 5 additions & 20 deletions tooling/bundler/src/bundle/windows/nsis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ use crate::{
bundle::{
common::CommandExt,
windows::util::{
download, download_and_verify, download_webview2_bootstrapper,
download_webview2_offline_installer, extract_zip, verify_file_hash, HashAlgorithm,
NSIS_OUTPUT_FOLDER_NAME, NSIS_UPDATER_OUTPUT_FOLDER_NAME,
download_and_verify, download_webview2_bootstrapper, download_webview2_offline_installer,
verify_file_hash, HashAlgorithm, NSIS_OUTPUT_FOLDER_NAME, NSIS_UPDATER_OUTPUT_FOLDER_NAME,
},
},
Settings,
Expand All @@ -24,7 +23,7 @@ use tauri_utils::config::{NSISInstallerMode, NsisCompression, WebviewInstallMode

use std::{
collections::{BTreeMap, HashMap},
fs::{copy, create_dir_all, remove_dir_all, rename, write},
fs::{create_dir_all, remove_dir_all, rename, write},
path::{Path, PathBuf},
process::Command,
};
Expand All @@ -35,7 +34,6 @@ const NSIS_URL: &str =
"https://github.com/tauri-apps/binary-releases/releases/download/nsis-3/nsis-3.zip";
#[cfg(target_os = "windows")]
const NSIS_SHA1: &str = "057e83c7d82462ec394af76c87d06733605543d4";
const NSIS_APPLICATIONID_URL: &str = "https://github.com/tauri-apps/binary-releases/releases/download/nsis-plugins-v0/NSIS-ApplicationID.zip";
const NSIS_TAURI_UTILS_URL: &str =
"https://github.com/tauri-apps/nsis-tauri-utils/releases/download/nsis_tauri_utils-v0.3.0/nsis_tauri_utils.dll";
const NSIS_TAURI_UTILS_SHA1: &str = "01E48D6429B48B640230C6CE8F257C84758943AA";
Expand Down Expand Up @@ -105,26 +103,13 @@ fn get_and_extract_nsis(nsis_toolset_path: &Path, _tauri_tools_path: &Path) -> c
#[cfg(target_os = "windows")]
{
let data = download_and_verify(NSIS_URL, NSIS_SHA1, HashAlgorithm::Sha1)?;
info!("extracting NSIS");
extract_zip(&data, _tauri_tools_path)?;
log::info!("extracting NSIS");
crate::bundle::windows::util::extract_zip(&data, _tauri_tools_path)?;
rename(_tauri_tools_path.join("nsis-3.08"), nsis_toolset_path)?;
}

let nsis_plugins = nsis_toolset_path.join("Plugins");

let data = download(NSIS_APPLICATIONID_URL)?;
info!("extracting NSIS ApplicationID plugin");
extract_zip(&data, &nsis_plugins)?;

create_dir_all(nsis_plugins.join("x86-unicode"))?;

copy(
nsis_plugins
.join("ReleaseUnicode")
.join("ApplicationID.dll"),
nsis_plugins.join("x86-unicode").join("ApplicationID.dll"),
)?;

let data = download_and_verify(
NSIS_TAURI_UTILS_URL,
NSIS_TAURI_UTILS_SHA1,
Expand Down
65 changes: 63 additions & 2 deletions tooling/bundler/src/bundle/windows/templates/installer.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Unicode true
!include x64.nsh
!include WordFunc.nsh
!include "StrFunc.nsh"
!include "Win\COM.nsh"
!include "Win\Propkey.nsh"
${StrCase}
${StrLoc}

Expand Down Expand Up @@ -621,6 +623,35 @@ Function un.onInit
!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

Expand All @@ -646,6 +677,10 @@ Section Uninstall
{{/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"
Expand Down Expand Up @@ -687,13 +722,39 @@ 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"
ApplicationID::Set "$DESKTOP\${MAINBINARYNAME}.lnk" "${BUNDLEID}"
!insertmacro SetLnkAppUserModelId "$DESKTOP\${MAINBINARYNAME}.lnk"
FunctionEnd

Function CreateStartMenuShortcut
CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder"
CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
ApplicationID::Set "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" "${BUNDLEID}"
!insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk"
FunctionEnd
3 changes: 2 additions & 1 deletion tooling/bundler/src/bundle/windows/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ pub fn verify_file_hash<P: AsRef<Path>>(
verify_hash(&data, hash, hash_algorithm)
}

/// Extracts the zips from memory into a useable path.
/// Extracts the zips from memory into a usable path.
#[allow(dead_code)]
pub fn extract_zip(data: &[u8], path: &Path) -> crate::Result<()> {
let cursor = Cursor::new(data);

Expand Down

0 comments on commit b8fd8e1

Please sign in to comment.