Skip to content

Commit

Permalink
fix(core): embed app manifest on Windows direclty
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir committed Aug 24, 2024
1 parent 5c369e6 commit 778ee4a
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 12 deletions.
6 changes: 6 additions & 0 deletions .changes/tauri-build-windows-app-manifest-path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri-build": "patch"
---

Add `WindowsAttributes::app_manifest_path` to specify a path to a Windows app manifest file.

93 changes: 85 additions & 8 deletions core/tauri-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ pub struct WindowsAttributes {
///
/// Defaults to:
/// ```text
#[doc = include_str!("window-app-manifest.xml")]
#[doc = include_str!("windows-app-manifest.xml")]
/// ```
///
/// ## Warning
Expand All @@ -253,6 +253,11 @@ pub struct WindowsAttributes {
///
/// [application manifest]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests
app_manifest: Option<String>,

/// Path to an [application manifest] file to be included with the application on Windows.
///
/// [application manifest]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests
app_manifest_path: Option<PathBuf>,
}

impl WindowsAttributes {
Expand All @@ -273,9 +278,11 @@ impl WindowsAttributes {

/// Sets the [application manifest] to be included with the application on Windows.
///
/// This options conflicts with [WindowsAttributes::app_manifest_path]
///
/// Defaults to:
/// ```text
#[doc = include_str!("window-app-manifest.xml")]
#[doc = include_str!("windows-app-manifest.xml")]
/// ```
///
/// ## Warning
Expand Down Expand Up @@ -327,6 +334,52 @@ impl WindowsAttributes {
self.app_manifest = Some(manifest.as_ref().to_string());
self
}

/// Path to an [application manifest] file to be included with the application on Windows.
///
/// This options conflicts with [WindowsAttributes::app_manifest]
///
/// Defaults to:
/// ```text
#[doc = include_str!("windows-app-manifest.xml")]
/// ```
///
/// ## Warning
///
/// if you are using tauri's dialog APIs, you need to specify a dependency on Common Control v6 by adding the following to your custom manifest:
/// ```text
/// <dependency>
/// <dependentAssembly>
/// <assemblyIdentity
/// type="win32"
/// name="Microsoft.Windows.Common-Controls"
/// version="6.0.0.0"
/// processorArchitecture="*"
/// publicKeyToken="6595b64144ccf1df"
/// language="*"
/// />
/// </dependentAssembly>
/// </dependency>
/// ```
///
/// # Example
///
/// The following manifest will brand the exe as requesting administrator privileges.
/// Thus, every time it is executed, a Windows UAC dialog will appear.
///
/// ```rust,no_run
/// let mut windows = tauri_build::WindowsAttributes::new();
/// windows = windows.app_manifest_file("./path/to/app-manifest.xml");
/// let attrs = tauri_build::Attributes::new().windows_attributes(windows);
/// tauri_build::try_build(attrs).expect("failed to run build script");
/// ```
///
/// [application manifest]: https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests
#[must_use]
pub fn app_manifest_path<P: AsRef<Path>>(mut self, file: P) -> Self {
self.app_manifest_path = Some(file.as_ref().to_path_buf());
self
}
}

/// The attributes used on the build.
Expand Down Expand Up @@ -626,6 +679,36 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
use semver::Version;
use tauri_winres::{VersionInfo, WindowsResource};

// Embed the Windows application manifest file directly instead of using a resource file.
// See https://github.com/tauri-apps/tauri/pull/10743#issuecomment-2307055443
// and https://github.com/tauri-apps/tauri/pull/4383#issuecomment-1212221864
let manifest_path = match (
attributes.windows_attributes.app_manifest,
attributes.windows_attributes.app_manifest_path,
) {
(Some(manifest), None) => {
let path = out_dir.join("windows-app-manifest.xml");
std::fs::write(&path, manifest).context("failed to write windows-app-manifest.xml")?;
path
}
(None, None) => {
let path = out_dir.join("windows-app-manifest.xml");
let manifest = include_str!("windows-app-manifest.xml");
std::fs::write(&path, manifest).context("failed to write windows-app-manifest.xml")?;
path
}
(None, Some(manifest_path)) => manifest_path,
(Some(_), Some(_)) => {
unreachable!("app_manifest and app_manifest_file can't be set at the same time")
}
};

println!("cargo:rustc-link-arg=/MANIFEST:EMBED");
println!(
"cargo:rustc-link-arg=/MANIFESTINPUT:{}",
manifest_path.display()
);

fn find_icon<F: Fn(&&String) -> bool>(config: &Config, predicate: F, default: &str) -> PathBuf {
let icon_path = config
.bundle
Expand All @@ -644,12 +727,6 @@ pub fn try_build(attributes: Attributes) -> Result<()> {

let mut res = WindowsResource::new();

if let Some(manifest) = attributes.windows_attributes.app_manifest {
res.set_manifest(&manifest);
} else {
res.set_manifest(include_str!("window-app-manifest.xml"));
}

if let Some(version_str) = &config.version {
if let Ok(v) = Version::parse(version_str) {
let version = v.major << 48 | v.minor << 32 | v.patch << 16;
Expand Down
8 changes: 4 additions & 4 deletions core/tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,12 @@ fn main() {
)
.expect("failed to write checked_features file");

// workaround needed to prevent `STATUS_ENTRYPOINT_NOT_FOUND` error
// workaround needed to prevent `STATUS_ENTRYPOINT_NOT_FOUND` error on tests
// see https://github.com/tauri-apps/tauri/pull/4383#issuecomment-1212221864
let target_env = std::env::var("CARGO_CFG_TARGET_ENV");
let is_tauri_workspace = std::env::var("__TAURI_WORKSPACE__").map_or(false, |v| v == "true");
if is_tauri_workspace && target_os == "windows" && Ok("msvc") == target_env.as_deref() {
add_manifest();
embed_windows_manifest_for_tests();
}

if target_os == "android" {
Expand Down Expand Up @@ -394,8 +394,8 @@ permissions = [{default_permissions}]
}
}

fn add_manifest() {
static WINDOWS_MANIFEST_FILE: &str = "window-app-manifest.xml";
fn embed_windows_manifest_for_tests() {
const WINDOWS_MANIFEST_FILE: &str = "windows-app-manifest.xml";

let manifest = std::env::current_dir()
.unwrap()
Expand Down

0 comments on commit 778ee4a

Please sign in to comment.