From d74f0bcafb49b85d0196cd2f5d34e714b35581ea Mon Sep 17 00:00:00 2001 From: zqm Date: Tue, 7 Apr 2026 12:49:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=90=8E=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CS/Framework4.0/BootLoader/src/main.rs | 120 +++++++++++++----- 1 file changed, 91 insertions(+), 29 deletions(-) diff --git a/Windows/CS/Framework4.0/BootLoader/src/main.rs b/Windows/CS/Framework4.0/BootLoader/src/main.rs index 7b019f7..5575cd3 100644 --- a/Windows/CS/Framework4.0/BootLoader/src/main.rs +++ b/Windows/CS/Framework4.0/BootLoader/src/main.rs @@ -2,83 +2,145 @@ use std::fs; use std::process::Command; use std::thread::sleep; use std::time::Duration; -use windows::Win32::System::Console; -use windows::Win32::Foundation::HWND; - -fn hide_console() { - unsafe { - let console = Console::GetConsoleWindow(); - if console != HWND::default() { - let _ = Console::FreeConsole(); - } - } -} fn main() { - // 隐藏控制台窗口 - hide_console(); - - // 检查是否已有 BootLoader 进程在运行 + // 检查是否已有多个 BootLoader 进程在运行 if is_process_running("BootLoader.exe") { + println!("Multiple BootLoader instances detected, exiting..."); return; } // 获取 BootLoader 启动目录所在盘的 AppData 目录 let appdata_dir = get_appdata_dir(); + println!("AppData directory: {:?}", appdata_dir); // 构建 Updater 相关文件路径 let updater_exe = appdata_dir.join("Updater.exe"); let updater_new_exe = appdata_dir.join("Updater.new.exe"); + println!("Updater.exe path: {:?}", updater_exe); + println!("Updater.new.exe path: {:?}", updater_new_exe); // 检查 Updater.new.exe 是否存在 if !updater_new_exe.exists() { + println!("Updater.new.exe does not exist, exiting..."); return; } // 等待 Updater 进程退出 - wait_for_process_exit("Updater.exe"); + println!("Waiting for Updater process to exit..."); + if !wait_for_process_exit("Updater.exe") { + // 超时,退出 BootLoader + println!("BootLoader exiting due to timeout..."); + return; + } + println!("Updater process exited"); // 直接覆盖 Updater.exe(fs::rename 在 Windows 上会自动替换已存在的文件) - fs::rename(&updater_new_exe, &updater_exe).expect("Failed to rename Updater.new.exe to Updater.exe"); + println!("Renaming Updater.new.exe to Updater.exe..."); + match fs::rename(&updater_new_exe, &updater_exe) { + Ok(_) => println!("Rename successful"), + Err(e) => println!("Rename failed: {:?}", e), + } // 启动 Updater.exe - Command::new(updater_exe) - .spawn() - .expect("Failed to start Updater.exe"); + println!("Starting Updater.exe..."); + println!("Updater.exe path: {:?}", updater_exe); + println!("Updater.exe exists: {:?}", updater_exe.exists()); + + match Command::new(updater_exe).spawn() { + Ok(child) => { + println!("Updater.exe started successfully with PID: {}", child.id()); + // 等待一点时间,确保 Updater 有足够的时间启动 + sleep(Duration::from_secs(1)); + // 检查 Updater 进程是否仍在运行 + if is_process_running("Updater.exe") { + println!("Updater.exe is running"); + } else { + println!("Updater.exe may have exited immediately"); + } + } + Err(e) => println!("Failed to start Updater.exe: {:?}", e), + } } fn is_process_running(process_name: &str) -> bool { + use std::process::id; + + let current_pid = id().to_string(); let output = Command::new("tasklist") - .args(["/FI", &format!("IMAGENAME eq {}", process_name)]) + .args(["/FI", &format!("IMAGENAME eq {}", process_name), "/FO", "CSV"]) .output() .expect("Failed to execute tasklist"); let output_str = String::from_utf8_lossy(&output.stdout); - output_str.contains(process_name) + + // 检查是否有其他同名进程 + let lines: Vec<&str> = output_str.lines().collect(); + let mut count = 0; + + for line in lines { + if line.contains(&format!("\"{}\"", process_name)) && !line.contains(¤t_pid) { + count += 1; + } + } + + // 如果有其他同名进程,则返回 true + count > 0 } fn get_appdata_dir() -> std::path::PathBuf { let exe_path = std::env::current_exe().expect("Failed to get executable path"); + println!("BootLoader executable path: {:?}", exe_path); let drive = if let Some(parent) = exe_path.parent() { - let drive = parent.as_os_str().to_str().unwrap_or("C:/").split('\\').next().unwrap_or("C:"); + println!("Parent directory: {:?}", parent); + let parent_str = parent.as_os_str().to_str().unwrap_or("C:/"); + println!("Parent directory string: {:?}", parent_str); + let drive = parent_str.split('\\').next().unwrap_or("C:"); + println!("Drive: {:?}", drive); std::path::Path::new(&format!("{}/", drive)).to_path_buf() } else { std::path::Path::new("C:/").to_path_buf() }; - drive.join("AppData").join("Updater") + let appdata_dir = drive.join("AppData"); + println!("Final AppData directory: {:?}", appdata_dir); + appdata_dir } -fn wait_for_process_exit(process_name: &str) { +fn wait_for_process_exit(process_name: &str) -> bool { + let mut attempts = 0; + let max_attempts = 300; // 30 seconds + loop { - // 使用 tasklist 命令检查进程是否存在 + // 使用 tasklist 命令检查进程是否存在,使用 CSV 格式以便更精确地匹配 let output = Command::new("tasklist") - .args(["/FI", &format!("IMAGENAME eq {}", process_name)]) + .args(["/FI", &format!("IMAGENAME eq {}", process_name), "/FO", "CSV"]) .output() .expect("Failed to execute tasklist"); let output_str = String::from_utf8_lossy(&output.stdout); - if !output_str.contains(process_name) { - break; + println!("Tasklist output for {}: {:?}", process_name, output_str); + + // 检查是否有精确匹配的进程名 + let mut process_found = false; + let lines: Vec<&str> = output_str.lines().collect(); + + for line in lines { + // 查找精确匹配的进程名 + if line.contains(&format!("\"{}\"", process_name)) { + process_found = true; + break; + } + } + + if !process_found { + println!("Process {} not found, continuing...", process_name); + return true; // 进程成功退出 + } + + attempts += 1; + if attempts > max_attempts { + println!("Timeout waiting for process {} to exit, exiting BootLoader...", process_name); + return false; // 超时,返回 false } // 等待 100 毫秒后再次检查