Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions crates/uffs-update/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,10 @@ windows.workspace = true
[target.'cfg(unix)'.dependencies]
libc = "0.2"

# Embed `app.manifest` (asInvoker) into uffs-update.exe on Windows MSVC so the
# "update" name doesn't trip Installer Detection → forced UAC (os error 740).
[build-dependencies]
winresource.workspace = true

[lints]
workspace = true
41 changes: 41 additions & 0 deletions crates/uffs-update/app.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
SPDX-FileCopyrightText: 2025-2026 SKY, LLC.
SPDX-License-Identifier: MPL-2.0

uffs-update application manifest.

CRITICAL: the `asInvoker` requestedExecutionLevel below is what stops
Windows' "Installer Detection" heuristic from force-elevating this binary.
That heuristic auto-flags executables whose NAME contains update/setup/
install/patch as installers needing UAC — so `uffs-update.exe` would
otherwise fail to launch from the non-elevated `uffs.exe` with
ERROR_ELEVATION_REQUIRED (os error 740), breaking every `uffs --update`
operation. The self-update helper only rewrites files in the user's own
install dir; it never needs Administrator.
-->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="UFFS.Update" version="0.0.0.0"/>

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>

<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<!-- Long-path support for deep install/staging paths (> 260 chars). -->
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 / 11 (shared supportedOS GUID per MS docs). -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>
46 changes: 46 additions & 0 deletions crates/uffs-update/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2025-2026 SKY, LLC.

// Build scripts run on the build host, not the shipping binary; the workspace
// deny-expect lint exists for runtime code. `expect` with a readable message is
// the idiomatic shape for build-script error reporting.
#![allow(
clippy::expect_used,
reason = "build scripts may panic on build-host failure; workspace deny-expect exists for runtime code"
)]

//! Build script: embed `app.manifest` into `uffs-update.exe` on Windows MSVC.
//!
//! The manifest declares `asInvoker`, which is **required** to stop Windows'
//! Installer Detection heuristic from force-elevating this binary purely
//! because its name contains "update". Without it, `uffs.exe` (non-elevated)
//! cannot spawn `uffs-update.exe` — it fails with `ERROR_ELEVATION_REQUIRED`
//! (os error 740) — breaking every `uffs --update` operation on Windows. The
//! helper only rewrites files in the user's install dir; it never needs admin.
//!
//! Inert on non-Windows / non-MSVC targets (the helper ships windows-msvc).

fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=app.manifest");
println!("cargo:rerun-if-changed=../../assets/brand/icons/uffs.ico");

let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();

if target_os == "windows" && target_env == "msvc" {
let mut res = winresource::WindowsResource::new();
res.set_icon("../../assets/brand/icons/uffs.ico")
.set("ProductName", "UltraFastFileSearch")
.set("FileDescription", "UFFS self-update helper")
.set("CompanyName", "SKY, LLC.")
.set("LegalCopyright", "(c) 2025-2026 SKY, LLC. MPL-2.0.")
.set("OriginalFilename", "uffs-update.exe")
.set_manifest_file("app.manifest");

// Panic on failure is fine in a build script (host-only; the
// workspace deny-unwrap lint targets runtime code).
res.compile()
.expect("winresource: failed to embed uffs-update manifest");
}
}
Loading