From f7784d0d28ddab537c6de284422a74441e657e50 Mon Sep 17 00:00:00 2001 From: Tony Date: Fri, 8 Mar 2024 15:28:54 +0800 Subject: [PATCH 1/8] Migrate to ShellExecute --- Cargo.lock | 86 ++++++++++++++++-------- plugins/updater/Cargo.toml | 26 +++++--- plugins/updater/src/updater.rs | 115 ++++++++------------------------- 3 files changed, 102 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fad46e8b5..17b02014c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1039,7 +1039,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -6793,6 +6793,7 @@ dependencies = [ "time", "tokio", "url", + "windows 0.54.0", "zip", ] @@ -8092,7 +8093,17 @@ dependencies = [ "windows-core 0.52.0", "windows-implement", "windows-interface", - "windows-targets 0.52.0", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +dependencies = [ + "windows-core 0.54.0", + "windows-targets 0.52.4", ] [[package]] @@ -8110,7 +8121,17 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-core" +version = "0.54.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +dependencies = [ + "windows-result", + "windows-targets 0.52.4", ] [[package]] @@ -8135,6 +8156,15 @@ dependencies = [ "syn 2.0.49", ] +[[package]] +name = "windows-result" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" +dependencies = [ + "windows-targets 0.52.4", +] + [[package]] name = "windows-sys" version = "0.36.1" @@ -8172,7 +8202,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -8207,17 +8237,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -8226,7 +8256,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75aa004c988e080ad34aff5739c39d0312f4684699d6d71fc8a198d057b8b9b4" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -8243,9 +8273,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -8267,9 +8297,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -8291,9 +8321,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -8315,9 +8345,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -8339,9 +8369,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -8357,9 +8387,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -8381,9 +8411,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "winnow" diff --git a/plugins/updater/Cargo.toml b/plugins/updater/Cargo.toml index 2440a6ecc..f6b9ee22a 100644 --- a/plugins/updater/Cargo.toml +++ b/plugins/updater/Cargo.toml @@ -9,11 +9,11 @@ rust-version = { workspace = true } links = "tauri-plugin-updater" [package.metadata.docs.rs] -rustc-args = [ "--cfg", "docsrs" ] -rustdoc-args = [ "--cfg", "docsrs" ] +rustc-args = ["--cfg", "docsrs"] +rustdoc-args = ["--cfg", "docsrs"] [build-dependencies] -tauri-plugin = { workspace = true, features = [ "build" ] } +tauri-plugin = { workspace = true, features = ["build"] } [dependencies] tauri = { workspace = true } @@ -21,15 +21,18 @@ serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } tokio = "1" -reqwest = { version = "0.11", default-features = false, features = [ "json", "stream" ] } +reqwest = { version = "0.11", default-features = false, features = [ + "json", + "stream", +] } url = { workspace = true } http = "0.2" dirs-next = "2" minisign-verify = "0.2" -time = { version = "0.3", features = [ "parsing", "formatting" ] } +time = { version = "0.3", features = ["parsing", "formatting"] } base64 = "0.21" percent-encoding = "2" -semver = { version = "1", features = [ "serde" ] } +semver = { version = "1", features = ["serde"] } futures-util = "0.3" tempfile = "3" zip = "0.6" @@ -37,6 +40,11 @@ tar = "0.4" [target."cfg(target_os = \"windows\")".dependencies] zip = { version = "0.6", default-features = false } +windows = { version = "0.54", features = [ + "Win32_System_WinRT", + "Win32_UI_Shell", + "Win32_UI_WindowsAndMessaging", +] } [target."cfg(any(target_os = \"macos\", target_os = \"linux\"))".dependencies] flate2 = "1.0.27" @@ -45,6 +53,6 @@ flate2 = "1.0.27" mockito = "0.31" [features] -native-tls = [ "reqwest/native-tls" ] -native-tls-vendored = [ "reqwest/native-tls-vendored" ] -rustls-tls = [ "reqwest/rustls-tls" ] +native-tls = ["reqwest/native-tls"] +native-tls-vendored = ["reqwest/native-tls-vendored"] +rustls-tls = ["reqwest/rustls-tls"] diff --git a/plugins/updater/src/updater.rs b/plugins/updater/src/updater.rs index 52b33e217..a57327520 100644 --- a/plugins/updater/src/updater.rs +++ b/plugins/updater/src/updater.rs @@ -514,6 +514,13 @@ impl Update { fn install_inner(&self, bytes: Vec) -> Result<()> { use std::{fs, process::Command}; + use windows::{ + core::{w, HSTRING}, + Win32::UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOW}, + }; + + use crate::config::WindowsUpdateInstallMode; + // FIXME: We need to create a memory buffer with the MSI and then run it. // (instead of extracting the MSI to a temp path) // @@ -534,118 +541,50 @@ impl Update { let paths = fs::read_dir(&tmp_dir)?; - let system_root = std::env::var("SYSTEMROOT"); - let powershell_path = system_root.as_ref().map_or_else( - |_| "powershell.exe".to_string(), - |p| format!("{p}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"), - ); - let install_mode = self .config .windows .as_ref() .map(|w| w.install_mode.clone()) .unwrap_or_default(); + let mut installer_args = self + .installer_args + .iter() + .map(|a| OsStr::new(a)) + .collect::>(); 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 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.extend( install_mode .nsis_args() .iter() .map(OsStr::new) .collect::>(), - self.installer_args - .iter() - .map(|a| a.as_os_str()) - .collect::>(), - ] - .concat(); - - // Run the installer - let mut cmd = Command::new(powershell_path); - - cmd.args(["-NoProfile", "-WindowStyle", "Hidden"]) - .args(["Start-Process"]) - .arg(installer_path); - - if !installer_args.is_empty() { - cmd.arg("-ArgumentList") - .arg(installer_args.join(OsStr::new(", "))); - } - cmd.spawn().expect("installer failed to start"); - - std::process::exit(0); + ); } else if found_path.extension() == Some(OsStr::new("msi")) { - // we need to wrap the current exe path in quotes for Start-Process - let mut current_exe_arg = std::ffi::OsString::new(); - current_exe_arg.push("\""); - current_exe_arg.push(current_exe()?); - current_exe_arg.push("\""); - - let mut msi_path = std::ffi::OsString::new(); - msi_path.push("\"\"\""); - msi_path.push(&found_path); - msi_path.push("\"\"\""); - - let installer_args = [ + installer_args.extend( install_mode .msiexec_args() .iter() .map(OsStr::new) .collect::>(), - self.installer_args - .iter() - .map(|a| a.as_os_str()) - .collect::>(), - ] - .concat(); - - // run the installer and relaunch the application - let powershell_install_res = Command::new(powershell_path) - .args(["-NoProfile", "-WindowStyle", "Hidden"]) - .args([ - "Start-Process", - "-Wait", - "-FilePath", - "$Env:SYSTEMROOT\\System32\\msiexec.exe", - "-ArgumentList", - ]) - .arg("/i,") - .arg(&msi_path) - .arg(format!( - ", {}, /promptrestart;", - installer_args.join(OsStr::new(", ")).to_string_lossy() - )) - .arg("Start-Process") - .arg(current_exe_arg) - .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(); - } - - std::process::exit(0); + ); + installer_args.push(OsStr::new("/promptrestart")); + } else { + continue; + } + let file = HSTRING::from(found_path.as_os_str()); + let parameters = HSTRING::from(installer_args.join(OsStr::new(" "))); + let ret = + unsafe { ShellExecuteW(None, w!("runas"), &file, ¶meters, None, SW_SHOW) }; + if ret.0 <= 32 { + return Err(Error::Io(windows::core::Error::from_win32().into())); } + std::process::exit(0); } Ok(()) From 8b0f76f1ec248b9ae5d91e7bf5f9664c309b4c1b Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Mar 2024 08:59:37 +0800 Subject: [PATCH 2/8] Add change file --- .changes/fix-updater-powershell-flashing.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changes/fix-updater-powershell-flashing.md diff --git a/.changes/fix-updater-powershell-flashing.md b/.changes/fix-updater-powershell-flashing.md new file mode 100644 index 000000000..a23b5b06c --- /dev/null +++ b/.changes/fix-updater-powershell-flashing.md @@ -0,0 +1,5 @@ +--- +"updater": patch +--- + +Fix Windows powershell window flashing on update From 6d23f172e8a7571a9a2d0d3f66346620529fa5de Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Mar 2024 09:29:09 +0800 Subject: [PATCH 3/8] Revert cargo.toml style --- plugins/updater/Cargo.toml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/plugins/updater/Cargo.toml b/plugins/updater/Cargo.toml index f6b9ee22a..73cd09922 100644 --- a/plugins/updater/Cargo.toml +++ b/plugins/updater/Cargo.toml @@ -9,11 +9,11 @@ rust-version = { workspace = true } links = "tauri-plugin-updater" [package.metadata.docs.rs] -rustc-args = ["--cfg", "docsrs"] -rustdoc-args = ["--cfg", "docsrs"] +rustc-args = [ "--cfg", "docsrs" ] +rustdoc-args = [ "--cfg", "docsrs" ] [build-dependencies] -tauri-plugin = { workspace = true, features = ["build"] } +tauri-plugin = { workspace = true, features = [ "build" ] } [dependencies] tauri = { workspace = true } @@ -21,18 +21,15 @@ serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } tokio = "1" -reqwest = { version = "0.11", default-features = false, features = [ - "json", - "stream", -] } +reqwest = { version = "0.11", default-features = false, features = [ "json", "stream" ] } url = { workspace = true } http = "0.2" dirs-next = "2" minisign-verify = "0.2" -time = { version = "0.3", features = ["parsing", "formatting"] } +time = { version = "0.3", features = [ "parsing", "formatting" ] } base64 = "0.21" percent-encoding = "2" -semver = { version = "1", features = ["serde"] } +semver = { version = "1", features = [ "serde" ] } futures-util = "0.3" tempfile = "3" zip = "0.6" @@ -53,6 +50,6 @@ flate2 = "1.0.27" mockito = "0.31" [features] -native-tls = ["reqwest/native-tls"] -native-tls-vendored = ["reqwest/native-tls-vendored"] -rustls-tls = ["reqwest/rustls-tls"] +native-tls = [ "reqwest/native-tls" ] +native-tls-vendored = [ "reqwest/native-tls-vendored" ] +rustls-tls = [ "reqwest/rustls-tls" ] From 67e12d71cf93f24bb6fa329f452b78ed6e4ec20a Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Mar 2024 09:29:40 +0800 Subject: [PATCH 4/8] Remove unused imports --- plugins/updater/src/updater.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/updater/src/updater.rs b/plugins/updater/src/updater.rs index a57327520..a64184b1d 100644 --- a/plugins/updater/src/updater.rs +++ b/plugins/updater/src/updater.rs @@ -512,15 +512,13 @@ impl Update { // Update server can provide a custom EXE (installer) who can run any task. #[cfg(windows)] fn install_inner(&self, bytes: Vec) -> Result<()> { - use std::{fs, process::Command}; + use std::fs; use windows::{ core::{w, HSTRING}, Win32::UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOW}, }; - use crate::config::WindowsUpdateInstallMode; - // FIXME: We need to create a memory buffer with the MSI and then run it. // (instead of extracting the MSI to a temp path) // From 5e3cc99b2ab1d3bf26c3788a3c0862e8ff004ee6 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Mar 2024 09:51:36 +0800 Subject: [PATCH 5/8] Migrate to windows-sys --- Cargo.lock | 31 +------------------------------ plugins/updater/Cargo.toml | 6 +----- plugins/updater/src/updater.rs | 30 ++++++++++++++++++++++-------- 3 files changed, 24 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 17b02014c..9dee2ec47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6793,7 +6793,7 @@ dependencies = [ "time", "tokio", "url", - "windows 0.54.0", + "windows-sys 0.52.0", "zip", ] @@ -8096,16 +8096,6 @@ dependencies = [ "windows-targets 0.52.4", ] -[[package]] -name = "windows" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" -dependencies = [ - "windows-core 0.54.0", - "windows-targets 0.52.4", -] - [[package]] name = "windows-core" version = "0.51.1" @@ -8124,16 +8114,6 @@ dependencies = [ "windows-targets 0.52.4", ] -[[package]] -name = "windows-core" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" -dependencies = [ - "windows-result", - "windows-targets 0.52.4", -] - [[package]] name = "windows-implement" version = "0.52.0" @@ -8156,15 +8136,6 @@ dependencies = [ "syn 2.0.49", ] -[[package]] -name = "windows-result" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" -dependencies = [ - "windows-targets 0.52.4", -] - [[package]] name = "windows-sys" version = "0.36.1" diff --git a/plugins/updater/Cargo.toml b/plugins/updater/Cargo.toml index 73cd09922..6159feb26 100644 --- a/plugins/updater/Cargo.toml +++ b/plugins/updater/Cargo.toml @@ -37,11 +37,7 @@ tar = "0.4" [target."cfg(target_os = \"windows\")".dependencies] zip = { version = "0.6", default-features = false } -windows = { version = "0.54", features = [ - "Win32_System_WinRT", - "Win32_UI_Shell", - "Win32_UI_WindowsAndMessaging", -] } +windows-sys = { version = "0.52.0", features = ["Win32_Foundation", "Win32_UI_WindowsAndMessaging"] } [target."cfg(any(target_os = \"macos\", target_os = \"linux\"))".dependencies] flate2 = "1.0.27" diff --git a/plugins/updater/src/updater.rs b/plugins/updater/src/updater.rs index a64184b1d..3c0608535 100644 --- a/plugins/updater/src/updater.rs +++ b/plugins/updater/src/updater.rs @@ -514,8 +514,9 @@ impl Update { fn install_inner(&self, bytes: Vec) -> Result<()> { use std::fs; - use windows::{ - core::{w, HSTRING}, + use windows_sys::{ + core::HSTRING, + w, Win32::UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOW}, }; @@ -575,12 +576,25 @@ impl Update { } else { continue; } - let file = HSTRING::from(found_path.as_os_str()); - let parameters = HSTRING::from(installer_args.join(OsStr::new(" "))); - let ret = - unsafe { ShellExecuteW(None, w!("runas"), &file, ¶meters, None, SW_SHOW) }; - if ret.0 <= 32 { - return Err(Error::Io(windows::core::Error::from_win32().into())); + let file = HSTRING::from(found_path.as_os_str().as_encoded_bytes().as_ptr() as _); + let parameters = HSTRING::from( + installer_args + .join(OsStr::new(" ")) + .as_encoded_bytes() + .as_ptr() as _, + ); + let ret = unsafe { + ShellExecuteW( + 0, + w!("runas"), + file as _, + parameters as _, + std::ptr::null(), + SW_SHOW, + ) + }; + if ret <= 32 { + return Err(Error::Io(std::io::Error::last_os_error())); } std::process::exit(0); } From 65c1cbb332999630d427eb63bc989f130277519b Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Mar 2024 10:37:51 +0800 Subject: [PATCH 6/8] Use open instead of runas --- plugins/updater/src/updater.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/updater/src/updater.rs b/plugins/updater/src/updater.rs index 3c0608535..2985c95a7 100644 --- a/plugins/updater/src/updater.rs +++ b/plugins/updater/src/updater.rs @@ -586,7 +586,7 @@ impl Update { let ret = unsafe { ShellExecuteW( 0, - w!("runas"), + w!("open"), file as _, parameters as _, std::ptr::null(), From ef3b70cab16b83d1b985f4f3f41e5a1d41b67ae1 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Mar 2024 10:47:08 +0800 Subject: [PATCH 7/8] Use encode_wide instead of hstring --- plugins/updater/src/updater.rs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/plugins/updater/src/updater.rs b/plugins/updater/src/updater.rs index 2985c95a7..b3f387f78 100644 --- a/plugins/updater/src/updater.rs +++ b/plugins/updater/src/updater.rs @@ -515,7 +515,6 @@ impl Update { use std::fs; use windows_sys::{ - core::HSTRING, w, Win32::UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOW}, }; @@ -576,19 +575,14 @@ impl Update { } else { continue; } - let file = HSTRING::from(found_path.as_os_str().as_encoded_bytes().as_ptr() as _); - let parameters = HSTRING::from( - installer_args - .join(OsStr::new(" ")) - .as_encoded_bytes() - .as_ptr() as _, - ); + let file = encode_wide(found_path.as_os_str()); + let parameters = encode_wide(installer_args.join(OsStr::new(" ")).as_os_str()); let ret = unsafe { ShellExecuteW( 0, w!("open"), - file as _, - parameters as _, + file.as_ptr(), + parameters.as_ptr(), std::ptr::null(), SW_SHOW, ) @@ -895,3 +889,14 @@ fn base64_to_string(base64_string: &str) -> Result { .to_string(); Ok(result) } + +#[cfg(target_os = "windows")] +fn encode_wide(string: impl AsRef) -> Vec { + use std::os::windows::ffi::OsStrExt; + + string + .as_ref() + .encode_wide() + .chain(std::iter::once(0)) + .collect() +} From 5bade347b540949ea48f47c22c6b6377043fcb44 Mon Sep 17 00:00:00 2001 From: amrbashir Date: Tue, 12 Mar 2024 16:21:36 +0200 Subject: [PATCH 8/8] small cleanup --- .../updater/permissions/schemas/schema.json | 10 ++----- plugins/updater/src/updater.rs | 28 ++++--------------- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/plugins/updater/permissions/schemas/schema.json b/plugins/updater/permissions/schemas/schema.json index 6d6a3c211..691359767 100644 --- a/plugins/updater/permissions/schemas/schema.json +++ b/plugins/updater/permissions/schemas/schema.json @@ -139,14 +139,10 @@ }, "platforms": { "description": "Target platforms this permission applies. By default all platforms are affected by this permission.", - "default": [ - "linux", - "macOS", - "windows", - "android", - "iOS" + "type": [ + "array", + "null" ], - "type": "array", "items": { "$ref": "#/definitions/Target" } diff --git a/plugins/updater/src/updater.rs b/plugins/updater/src/updater.rs index b3f387f78..4ba744358 100644 --- a/plugins/updater/src/updater.rs +++ b/plugins/updater/src/updater.rs @@ -513,7 +513,6 @@ impl Update { #[cfg(windows)] fn install_inner(&self, bytes: Vec) -> Result<()> { use std::fs; - use windows_sys::{ w, Win32::UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOW}, @@ -526,15 +525,9 @@ impl Update { // 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. - let archive = Cursor::new(bytes); - let tmp_dir = tempfile::Builder::new().tempdir()?.into_path(); - - // extract the buffer to the tmp_dir - // we extract our signed archive into our final directory without any temp file + let archive = Cursor::new(bytes); let mut extractor = zip::ZipArchive::new(archive)?; - - // extract the msi extractor.extract(&tmp_dir)?; let paths = fs::read_dir(&tmp_dir)?; @@ -554,27 +547,16 @@ impl Update { 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")) { - installer_args.extend( - install_mode - .nsis_args() - .iter() - .map(OsStr::new) - .collect::>(), - ); + installer_args.extend(install_mode.nsis_args().iter().map(OsStr::new)); } else if found_path.extension() == Some(OsStr::new("msi")) { - installer_args.extend( - install_mode - .msiexec_args() - .iter() - .map(OsStr::new) - .collect::>(), - ); + installer_args.extend(install_mode.msiexec_args().iter().map(OsStr::new)); installer_args.push(OsStr::new("/promptrestart")); } else { continue; } + let file = encode_wide(found_path.as_os_str()); let parameters = encode_wide(installer_args.join(OsStr::new(" ")).as_os_str()); let ret = unsafe {