From 2b7d03f3c8d36221c9f839beb25a905568be9a71 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Fri, 16 Oct 2026 09:45:19 +0200 Subject: [PATCH] Embedded the Windows app manifest into the Rust test programs (#1071) --- runtime/build.rs | 41 +++++++++++++++++++++++++++++++- runtime/windows-app-manifest.xml | 19 +++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 runtime/windows-app-manifest.xml diff --git a/runtime/build.rs b/runtime/build.rs index 2fecf9eb8..76e480a92 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -1,7 +1,24 @@ use std::path::{PathBuf}; fn main() { - tauri_build::build(); + // + // On Windows, the dialogs need version 6 of the common controls, which + // the application manifest requests. Tauri's build helper embeds its + // manifest into the app only, not into the test programs, and Windows + // stops a test program without it before the first test runs. Hence, + // we embed the manifest ourselves wherever MSVC links, and Tauri's + // build helper must not add its own one as well: + // + let windows_attributes = if embed_windows_manifest() { + tauri_build::WindowsAttributes::new_without_app_manifest() + } else { + tauri_build::WindowsAttributes::new() + }; + + let tauri_attributes = tauri_build::Attributes::new().windows_attributes(windows_attributes); + if let Err(error) = tauri_build::try_build(tauri_attributes) { + panic!("Tauri's build helper failed: {error:#}"); + } let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap()); println!("cargo:rustc-env=OUT_DIR={}", out_dir.to_str().unwrap()); @@ -44,6 +61,28 @@ fn main() { update_tauri_conf("tauri.conf.json", version); } +/// Lets the linker embed our Windows application manifest into every program +/// it links: the app as well as the test programs. Tauri's build helper adds +/// its manifest only to the app. Tauri works around the same problem for its +/// own tests, see https://github.com/tauri-apps/tauri/pull/4383#issuecomment-1212221864 +/// +/// Returns false for all targets other than Windows with MSVC, where Tauri's +/// build helper keeps embedding its manifest. We read the target from Cargo, +/// since it differs from the building machine when we cross-compile. +fn embed_windows_manifest() -> bool { + let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); + let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap(); + if target_os != "windows" || target_env != "msvc" { + return false; + } + + let manifest = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("windows-app-manifest.xml"); + println!("cargo:rerun-if-changed={}", manifest.to_str().unwrap()); + println!("cargo:rustc-link-arg=/MANIFEST:EMBED"); + println!("cargo:rustc-link-arg=/MANIFESTINPUT:{}", manifest.to_str().unwrap()); + true +} + fn update_cargo_toml(cargo_path: &str, version: &str) { let cargo_toml = std::fs::read_to_string(cargo_path).unwrap(); let cargo_toml_lines = cargo_toml.lines(); diff --git a/runtime/windows-app-manifest.xml b/runtime/windows-app-manifest.xml new file mode 100644 index 000000000..1003c698f --- /dev/null +++ b/runtime/windows-app-manifest.xml @@ -0,0 +1,19 @@ + + + + + + + + \ No newline at end of file