refactor(nsis): use nsis's built-in com plugin instead of ApplicationID plugin (#9527)

* 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
This commit is contained in:
Tony 2024-04-24 22:14:30 +08:00 committed by GitHub
parent 12b4159bda
commit 68c39b8c0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 74 additions and 26 deletions

View File

@ -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 150-200 KB, and also fixes pinned shortcut not getting cleaned up on uninstall

View File

@ -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,
@ -23,7 +22,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,
};
@ -34,7 +33,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.2.2/nsis_tauri_utils.dll";
const NSIS_TAURI_UTILS_SHA1: &str = "16DF1D1A5B4D5DF3859447279C55BE36D4109DFB";
@ -45,7 +43,6 @@ const NSIS_REQUIRED_FILES: &[&str] = &[
"Bin/makensis.exe",
"Stubs/lzma-x86-unicode",
"Stubs/lzma_solid-x86-unicode",
"Plugins/x86-unicode/ApplicationID.dll",
"Plugins/x86-unicode/nsis_tauri_utils.dll",
"Include/MUI2.nsh",
"Include/FileFunc.nsh",
@ -54,10 +51,7 @@ const NSIS_REQUIRED_FILES: &[&str] = &[
"Include/WinMessages.nsh",
];
#[cfg(not(target_os = "windows"))]
const NSIS_REQUIRED_FILES: &[&str] = &[
"Plugins/x86-unicode/ApplicationID.dll",
"Plugins/x86-unicode/nsis_tauri_utils.dll",
];
const NSIS_REQUIRED_FILES: &[&str] = &["Plugins/x86-unicode/nsis_tauri_utils.dll"];
const NSIS_REQUIRED_FILES_HASH: &[(&str, &str, &str, HashAlgorithm)] = &[(
"Plugins/x86-unicode/nsis_tauri_utils.dll",
@ -109,25 +103,12 @@ fn get_and_extract_nsis(nsis_toolset_path: &Path, _tauri_tools_path: &Path) -> c
{
let data = download_and_verify(NSIS_URL, NSIS_SHA1, HashAlgorithm::Sha1)?;
log::info!("extracting NSIS");
extract_zip(&data, _tauri_tools_path)?;
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)?;
log::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,

View File

@ -13,6 +13,8 @@ ManifestDPIAware true
!include WordFunc.nsh
!include "FileAssociation.nsh"
!include "StrFunc.nsh"
!include "Win\COM.nsh"
!include "Win\Propkey.nsh"
${StrCase}
${StrLoc}
@ -644,6 +646,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
@ -685,6 +716,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"
@ -726,13 +761,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

View File

@ -132,6 +132,7 @@ pub fn verify_file_hash<P: AsRef<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);