mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-09-11 07:55:34 +03:00
refactor(updater/nsis): migrate run updater using powershell to ShellExecute (#9818)
This commit is contained in:
parent
d78fa20d86
commit
50aabad1f6
5
.changes/shellexecute-updater.md
Normal file
5
.changes/shellexecute-updater.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": patch:bug
|
||||
---
|
||||
|
||||
On Windows, fix flashing PowerShell for updates for NSIS installer, and address possible "permission denied" problems.
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -4021,7 +4021,7 @@ checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
|
||||
|
||||
[[package]]
|
||||
name = "tauri"
|
||||
version = "1.6.5"
|
||||
version = "1.6.6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.7",
|
||||
|
@ -119,7 +119,7 @@ win7-notifications = { version = "0.4", optional = true }
|
||||
|
||||
[target."cfg(windows)".dependencies.windows]
|
||||
version = "0.39.0"
|
||||
features = [ "Win32_Foundation" ]
|
||||
features = [ "Win32_Foundation", "Win32_UI_WindowsAndMessaging", "Win32_UI_Shell" ]
|
||||
|
||||
[build-dependencies]
|
||||
heck = "0.5"
|
||||
|
@ -815,6 +815,15 @@ fn copy_files_and_run<R: Read + Seek>(
|
||||
// shouldn't drop but we should be able to pass the reference so we can drop it once the installation
|
||||
// is done, otherwise we have a huge memory leak.
|
||||
|
||||
use windows::{
|
||||
core::{HSTRING, PCWSTR},
|
||||
w,
|
||||
Win32::{
|
||||
Foundation::HWND,
|
||||
UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOW},
|
||||
},
|
||||
};
|
||||
|
||||
let tmp_dir = tempfile::Builder::new().tempdir()?.into_path();
|
||||
|
||||
// extract the buffer to the tmp_dir
|
||||
@ -832,20 +841,14 @@ fn copy_files_and_run<R: Read + Seek>(
|
||||
|p| format!("{p}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"),
|
||||
);
|
||||
|
||||
let current_exe_args = env.args.clone();
|
||||
let mut installer_args_shellexecute;
|
||||
|
||||
for path in paths {
|
||||
let found_path = path?.path();
|
||||
// we support 2 type of files exe & msi for now
|
||||
// If it's an `exe` we expect an installer not a runtime.
|
||||
// If it's an `exe` we expect an NSIS installer.
|
||||
if found_path.extension() == Some(OsStr::new("exe")) {
|
||||
// we need to wrap the installer path in quotes for Start-Process
|
||||
let mut installer_path = std::ffi::OsString::new();
|
||||
installer_path.push("\"");
|
||||
installer_path.push(&found_path);
|
||||
installer_path.push("\"");
|
||||
|
||||
let installer_args = [
|
||||
installer_args_shellexecute = [
|
||||
config
|
||||
.tauri
|
||||
.updater
|
||||
@ -853,34 +856,13 @@ fn copy_files_and_run<R: Read + Seek>(
|
||||
.install_mode
|
||||
.nsis_args()
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.map(|a| a.to_string())
|
||||
.collect(),
|
||||
vec!["/ARGS".to_string()],
|
||||
current_exe_args,
|
||||
config
|
||||
.tauri
|
||||
.updater
|
||||
.windows
|
||||
.installer_args
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect::<Vec<_>>(),
|
||||
env.args.clone(),
|
||||
config.tauri.updater.windows.installer_args.clone(),
|
||||
]
|
||||
.concat();
|
||||
|
||||
// Run the EXE
|
||||
let mut cmd = Command::new(powershell_path);
|
||||
cmd
|
||||
.args(["-NoProfile", "-WindowStyle", "Hidden", "Start-Process"])
|
||||
.arg(installer_path);
|
||||
if !installer_args.is_empty() {
|
||||
cmd.arg("-ArgumentList").arg(installer_args.join(", "));
|
||||
}
|
||||
cmd
|
||||
.spawn()
|
||||
.expect("Running NSIS installer from powershell has failed to start");
|
||||
|
||||
exit(0);
|
||||
} else if found_path.extension() == Some(OsStr::new("msi")) {
|
||||
if with_elevated_task {
|
||||
if let Some(bin_name) = current_exe()
|
||||
@ -932,7 +914,7 @@ fn copy_files_and_run<R: Read + Seek>(
|
||||
msi_path.push(&found_path);
|
||||
msi_path.push("\"\"\"");
|
||||
|
||||
let installer_args = [
|
||||
let msi_installer_args = [
|
||||
config.tauri.updater.windows.install_mode.msiexec_args(),
|
||||
config
|
||||
.tauri
|
||||
@ -960,34 +942,57 @@ fn copy_files_and_run<R: Read + Seek>(
|
||||
])
|
||||
.arg("/i,")
|
||||
.arg(&msi_path)
|
||||
.arg(format!(", {}, /promptrestart;", installer_args.join(", ")))
|
||||
.arg(format!(
|
||||
", {}, /promptrestart;",
|
||||
msi_installer_args.join(", ")
|
||||
))
|
||||
.arg("Start-Process")
|
||||
.arg(current_executable);
|
||||
|
||||
if !current_exe_args.is_empty() {
|
||||
powershell_cmd
|
||||
.arg("-ArgumentList")
|
||||
.arg(current_exe_args.join(", "));
|
||||
if !env.args.is_empty() {
|
||||
powershell_cmd.arg("-ArgumentList").arg(env.args.join(", "));
|
||||
}
|
||||
|
||||
let powershell_install_res = powershell_cmd.spawn();
|
||||
if powershell_install_res.is_err() {
|
||||
// fallback to running msiexec directly - relaunch won't be available
|
||||
// we use this here in case powershell fails in an older machine somehow
|
||||
let msiexec_path = system_root.as_ref().map_or_else(
|
||||
|_| "msiexec.exe".to_string(),
|
||||
|p| format!("{p}\\System32\\msiexec.exe"),
|
||||
);
|
||||
let _ = Command::new(msiexec_path)
|
||||
.arg("/i")
|
||||
.arg(msi_path)
|
||||
.args(installer_args)
|
||||
.arg("/promptrestart")
|
||||
.spawn();
|
||||
installer_args_shellexecute = [
|
||||
config
|
||||
.tauri
|
||||
.updater
|
||||
.windows
|
||||
.install_mode
|
||||
.msiexec_args()
|
||||
.iter()
|
||||
.map(|a| a.to_string())
|
||||
.collect(),
|
||||
config.tauri.updater.windows.installer_args.clone(),
|
||||
]
|
||||
.concat();
|
||||
installer_args_shellexecute.push("/promptrestart".to_string());
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
let file = HSTRING::from(found_path.as_os_str());
|
||||
let parameters = HSTRING::from(installer_args_shellexecute.join(" "));
|
||||
let ret = unsafe {
|
||||
ShellExecuteW(
|
||||
HWND(0),
|
||||
w!("open"),
|
||||
&file,
|
||||
¶meters,
|
||||
PCWSTR::null(),
|
||||
SW_SHOW.0 as _,
|
||||
)
|
||||
};
|
||||
if ret.0 <= 32 {
|
||||
return Err(Error::Io(std::io::Error::last_os_error()));
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
Loading…
Reference in New Issue
Block a user