From d111ee5aa170906448b24c83cb682e9bc338b2e6 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 6 May 2025 17:50:08 +0800 Subject: [PATCH 1/4] windows: Run --versions command if double-clicked Signed-off-by: Daniel Schaefer --- Cargo.lock | 1 + framework_tool/Cargo.toml | 6 ++++++ framework_tool/src/main.rs | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 465dc6e0..3ee80253 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -424,6 +424,7 @@ version = "0.4.0" dependencies = [ "framework_lib", "static_vcruntime", + "winapi", ] [[package]] diff --git a/framework_tool/Cargo.toml b/framework_tool/Cargo.toml index da69ded0..bc30ab61 100644 --- a/framework_tool/Cargo.toml +++ b/framework_tool/Cargo.toml @@ -9,3 +9,9 @@ path = "../framework_lib" [build-dependencies] # Note: Only takes effect in release builds static_vcruntime = "2.0" + +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3.9" +features = [ + "wincon" +] diff --git a/framework_tool/src/main.rs b/framework_tool/src/main.rs index 3a4d54a4..251f85f4 100644 --- a/framework_tool/src/main.rs +++ b/framework_tool/src/main.rs @@ -6,9 +6,42 @@ fn get_args() -> Vec { } fn main() -> Result<(), &'static str> { - let args = commandline::parse(&get_args()); + let args = get_args(); + + // If the user double-clicks (opens from explorer/desktop), + // then we want to have the default behavior of showing a report of + // all firmware versions. + #[cfg(windows)] + let (args, double_clicked) = { + let double_clicked = unsafe { + // See https://devblogs.microsoft.com/oldnewthing/20160125-00/?p=92922 + let mut plist: winapi::shared::minwindef::DWORD = 0; + let processes = winapi::um::wincon::GetConsoleProcessList(&mut plist, 1); + processes == 1 + }; + if double_clicked { + ( + vec![args[0].clone(), "--versions".to_string()], + double_clicked, + ) + } else { + (args, double_clicked) + } + }; + + let args = commandline::parse(&args); if (commandline::run_with_args(&args, false)) != 0 { return Err("Fail"); } + + // Prevent command prompt from auto closing + #[cfg(windows)] + if double_clicked { + println!(); + println!("Press ENTER to exit..."); + let mut line = String::new(); + let _ = std::io::stdin().read_line(&mut line).unwrap(); + } + Ok(()) } From 7336362ac1b22f945226168ad903c83bee279b82 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 6 May 2025 05:47:04 -0700 Subject: [PATCH 2/4] windows: Embed resource to always launch as admin Only in release builds, because running `cargo run` from non-admin terminal won't work with the resources. Signed-off-by: Daniel Schaefer --- Cargo.lock | 128 ++++++++++++++++++++- framework_tool/Cargo.toml | 1 + framework_tool/build.rs | 10 +- framework_tool/framework_tool-manifest.rc | 2 + framework_tool/framework_tool.exe.manifest | 10 ++ 5 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 framework_tool/framework_tool-manifest.rc create mode 100644 framework_tool/framework_tool.exe.manifest diff --git a/Cargo.lock b/Cargo.lock index 3ee80253..fb0f76b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,7 +127,7 @@ checksum = "031718ddb8f78aa5def78a09e90defe30151d1f6c672f937af4dd916429ed996" dependencies = [ "semver", "serde", - "toml", + "toml 0.5.11", "url", ] @@ -354,6 +354,20 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "embed-resource" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fbc6e0d8e0c03a655b53ca813f0463d2c956bc4db8138dbc89f120b066551e3" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 0.8.22", + "vswhom", + "winreg", +] + [[package]] name = "env_filter" version = "0.1.2" @@ -377,6 +391,12 @@ dependencies = [ "log", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "form_urlencoded" version = "1.1.0" @@ -422,6 +442,7 @@ dependencies = [ name = "framework_tool" version = "0.4.0" dependencies = [ + "embed-resource", "framework_lib", "static_vcruntime", "winapi", @@ -567,6 +588,12 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "hashbrown" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" + [[package]] name = "heck" version = "0.5.0" @@ -626,6 +653,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "indexmap" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "io-kit-sys" version = "0.1.0" @@ -1070,6 +1107,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "sha2" version = "0.10.8" @@ -1208,6 +1254,47 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076" + [[package]] name = "typenum" version = "1.16.0" @@ -1313,6 +1400,26 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "wasm-bindgen" version = "0.2.84" @@ -1673,6 +1780,25 @@ version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +[[package]] +name = "winnow" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "wmi" version = "0.15.0" diff --git a/framework_tool/Cargo.toml b/framework_tool/Cargo.toml index bc30ab61..598d00c0 100644 --- a/framework_tool/Cargo.toml +++ b/framework_tool/Cargo.toml @@ -9,6 +9,7 @@ path = "../framework_lib" [build-dependencies] # Note: Only takes effect in release builds static_vcruntime = "2.0" +embed-resource = "3.0" [target.'cfg(windows)'.dependencies.winapi] version = "0.3.9" diff --git a/framework_tool/build.rs b/framework_tool/build.rs index 20e1c8e9..de98f1f6 100644 --- a/framework_tool/build.rs +++ b/framework_tool/build.rs @@ -1,3 +1,11 @@ fn main() { - static_vcruntime::metabuild(); + if !cfg!(debug_assertions) { + // Statically link vcruntime to allow running on clean install + static_vcruntime::metabuild(); + + // Embed resources file to force running as admin + embed_resource::compile("framework_tool-manifest.rc", embed_resource::NONE) + .manifest_optional() + .unwrap(); + } } diff --git a/framework_tool/framework_tool-manifest.rc b/framework_tool/framework_tool-manifest.rc new file mode 100644 index 00000000..68429585 --- /dev/null +++ b/framework_tool/framework_tool-manifest.rc @@ -0,0 +1,2 @@ +#define RT_MANIFEST 24 +1 RT_MANIFEST "framework_tool.exe.manifest" diff --git a/framework_tool/framework_tool.exe.manifest b/framework_tool/framework_tool.exe.manifest new file mode 100644 index 00000000..287bba26 --- /dev/null +++ b/framework_tool/framework_tool.exe.manifest @@ -0,0 +1,10 @@ + + + + + + + + + + From 079af34d4b4d995ac9e0d78921f5f6201fdd3421 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 7 May 2025 10:59:37 +0800 Subject: [PATCH 3/4] windows: Don't run --versions if any arguments provided Should always try to run as admin in release builds. But only autorun --versions if no arguments provided. Tested: - [x] Release Build with args - [x] Run from powershell - [x] Run from powershell with sudo "In new window" - [x] Run from powershell with sudo "With input disabled" - [x] Doubleclick from Explorer - This is impossible - [x] Release Build without args - [x] Run from powershell - This case autoruns --versions when it shouldn't - [x] Run from powershell with sudo "In new window" - This case autoruns --versions when it shouldn't - [x] Run from powershell with sudo "With input disabled" - [x] Doubleclick from Explorer - [x] Debug Build with args - [x] Run from powershell - [x] Run from powershell with sudo "In new window" - [x] Run from powershell with sudo "With input disabled" - [x] Doubleclick from Explorer - This is impossible - [x] Debug Build without args - [x] Run from powershell - [x] Run from powershell with sudo "In new window" - This case autoruns --versions when it shouldn't - [x] Run from powershell with sudo "With input disabled" - [x] Doubleclick from Explorer Signed-off-by: Daniel Schaefer --- framework_tool/src/main.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/framework_tool/src/main.rs b/framework_tool/src/main.rs index 251f85f4..d755aa77 100644 --- a/framework_tool/src/main.rs +++ b/framework_tool/src/main.rs @@ -17,9 +17,16 @@ fn main() -> Result<(), &'static str> { // See https://devblogs.microsoft.com/oldnewthing/20160125-00/?p=92922 let mut plist: winapi::shared::minwindef::DWORD = 0; let processes = winapi::um::wincon::GetConsoleProcessList(&mut plist, 1); + + // If we're the only process that means we're in a fresh terminal + // without CMD or powershell. This happens in some cases, for example + // if the user double-clicks the app from Explorer. processes == 1 }; - if double_clicked { + // But it also happens if launched from the commandline and a UAC prompt is necessary, + // for example with sudo set to open "In a new windows", therefore we also have to + // check that no commandline arguments were provided. + if double_clicked && args.len() == 1 { ( vec![args[0].clone(), "--versions".to_string()], double_clicked, From 4056948f290885ae577f651b0d850973a6dcfd51 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Wed, 17 Jul 2024 17:18:09 +0800 Subject: [PATCH 4/4] windows: Add app icon Signed-off-by: Daniel Schaefer --- Cargo.lock | 11 +++++++++++ framework_tool/Cargo.toml | 1 + framework_tool/build.rs | 8 ++++++++ res/framework_startmenuicon.ico | Bin 0 -> 89962 bytes 4 files changed, 20 insertions(+) create mode 100644 res/framework_startmenuicon.ico diff --git a/Cargo.lock b/Cargo.lock index fb0f76b6..86d1a77c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,6 +446,7 @@ dependencies = [ "framework_lib", "static_vcruntime", "winapi", + "winresource", ] [[package]] @@ -1799,6 +1800,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winresource" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4a67c78ee5782c0c1cb41bebc7e12c6e79644daa1650ebbc1de5d5b08593f7" +dependencies = [ + "toml 0.8.22", + "version_check", +] + [[package]] name = "wmi" version = "0.15.0" diff --git a/framework_tool/Cargo.toml b/framework_tool/Cargo.toml index 598d00c0..0469dab3 100644 --- a/framework_tool/Cargo.toml +++ b/framework_tool/Cargo.toml @@ -10,6 +10,7 @@ path = "../framework_lib" # Note: Only takes effect in release builds static_vcruntime = "2.0" embed-resource = "3.0" +winresource = "0.1.17" [target.'cfg(windows)'.dependencies.winapi] version = "0.3.9" diff --git a/framework_tool/build.rs b/framework_tool/build.rs index de98f1f6..87d2140e 100644 --- a/framework_tool/build.rs +++ b/framework_tool/build.rs @@ -1,4 +1,12 @@ fn main() { + // Add app icon + if std::env::var_os("CARGO_CFG_WINDOWS").is_some() { + winresource::WindowsResource::new() + .set_icon("..\\res\\framework_startmenuicon.ico") + .compile() + .unwrap(); + } + if !cfg!(debug_assertions) { // Statically link vcruntime to allow running on clean install static_vcruntime::metabuild(); diff --git a/res/framework_startmenuicon.ico b/res/framework_startmenuicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8c6be29a6b1462e13005c3c113d81888f51b73ab GIT binary patch literal 89962 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 P!S%KZZ+yQv)_?v#QgVSl literal 0 HcmV?d00001