fix can't run from cmd on win7 (#13160)

Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
21pages
2025-10-14 12:11:05 +08:00
committed by GitHub
parent 6f9728f2d4
commit 2c088d3504
3 changed files with 92 additions and 43 deletions

View File

@@ -15,6 +15,14 @@ md5 = "0.7"
winapi = { version = "0.3", features = ["winbase"] }
[target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.61", features = [
"Wdk",
"Wdk_System",
"Wdk_System_SystemServices",
"Win32",
"Win32_System",
"Win32_System_SystemInformation",
] }
native-windows-gui = {version = "1.0", default-features = false, features = ["animation-timer", "image-decoder"]}
[package.metadata.winres]

View File

@@ -92,12 +92,46 @@ fn setup(
}
write_meta(&dir, ts);
#[cfg(windows)]
windows::copy_runtime_broker(&dir);
win::copy_runtime_broker(&dir);
#[cfg(linux)]
reader.configure_permission(&dir);
Some(dir.join(&reader.exe))
}
fn use_null_stdio() -> bool {
#[cfg(windows)]
{
// When running in CMD on Windows 7, using Stdio::inherit() with spawn returns an "invalid handle" error.
// Since using Stdio::null() didnt cause any issues, and determining whether the program is launched from CMD or by double-clicking would require calling more APIs during startup, we also use Stdio::null() when launched by double-clicking on Windows 7.
let is_windows_7 = is_windows_7();
println!("is windows7: {}", is_windows_7);
return is_windows_7;
}
#[cfg(not(windows))]
false
}
#[cfg(windows)]
fn is_windows_7() -> bool {
use windows::Wdk::System::SystemServices::RtlGetVersion;
use windows::Win32::System::SystemInformation::OSVERSIONINFOW;
unsafe {
let mut version_info = OSVERSIONINFOW::default();
version_info.dwOSVersionInfoSize = std::mem::size_of::<OSVERSIONINFOW>() as u32;
if RtlGetVersion(&mut version_info).is_ok() {
// Windows 7 is version 6.1
println!(
"Windows version: {}.{}",
version_info.dwMajorVersion, version_info.dwMinorVersion
);
return version_info.dwMajorVersion == 6 && version_info.dwMinorVersion == 1;
}
}
false
}
fn execute(path: PathBuf, args: Vec<String>, _ui: bool) {
println!("executing {}", path.display());
// setup env
@@ -114,12 +148,18 @@ fn execute(path: PathBuf, args: Vec<String>, _ui: bool) {
cmd.env(SET_FOREGROUND_WINDOW_ENV_KEY, "1");
}
}
let _child = cmd
.env(APPNAME_RUNTIME_ENV_KEY, exe_name)
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn();
cmd.env(APPNAME_RUNTIME_ENV_KEY, exe_name);
if use_null_stdio() {
cmd.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null());
} else {
cmd.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit());
}
let _child = cmd.spawn();
#[cfg(windows)]
if _ui {
@@ -168,7 +208,7 @@ fn main() {
}
#[cfg(windows)]
mod windows {
mod win {
use std::{fs, os::windows::process::CommandExt, path::Path, process::Command};
// Used for privacy mode(magnifier impl).