升级后执行
This commit is contained in:
@@ -2,84 +2,146 @@ use std::fs;
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
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() {
|
fn main() {
|
||||||
// 隐藏控制台窗口
|
// 检查是否已有多个 BootLoader 进程在运行
|
||||||
hide_console();
|
|
||||||
|
|
||||||
// 检查是否已有 BootLoader 进程在运行
|
|
||||||
if is_process_running("BootLoader.exe") {
|
if is_process_running("BootLoader.exe") {
|
||||||
|
println!("Multiple BootLoader instances detected, exiting...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取 BootLoader 启动目录所在盘的 AppData 目录
|
// 获取 BootLoader 启动目录所在盘的 AppData 目录
|
||||||
let appdata_dir = get_appdata_dir();
|
let appdata_dir = get_appdata_dir();
|
||||||
|
println!("AppData directory: {:?}", appdata_dir);
|
||||||
|
|
||||||
// 构建 Updater 相关文件路径
|
// 构建 Updater 相关文件路径
|
||||||
let updater_exe = appdata_dir.join("Updater.exe");
|
let updater_exe = appdata_dir.join("Updater.exe");
|
||||||
let updater_new_exe = appdata_dir.join("Updater.new.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 是否存在
|
// 检查 Updater.new.exe 是否存在
|
||||||
if !updater_new_exe.exists() {
|
if !updater_new_exe.exists() {
|
||||||
|
println!("Updater.new.exe does not exist, exiting...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待 Updater 进程退出
|
// 等待 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 上会自动替换已存在的文件)
|
// 直接覆盖 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
|
// 启动 Updater.exe
|
||||||
Command::new(updater_exe)
|
println!("Starting Updater.exe...");
|
||||||
.spawn()
|
println!("Updater.exe path: {:?}", updater_exe);
|
||||||
.expect("Failed to start 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 {
|
fn is_process_running(process_name: &str) -> bool {
|
||||||
|
use std::process::id;
|
||||||
|
|
||||||
|
let current_pid = id().to_string();
|
||||||
let output = Command::new("tasklist")
|
let output = Command::new("tasklist")
|
||||||
.args(["/FI", &format!("IMAGENAME eq {}", process_name)])
|
.args(["/FI", &format!("IMAGENAME eq {}", process_name), "/FO", "CSV"])
|
||||||
.output()
|
.output()
|
||||||
.expect("Failed to execute tasklist");
|
.expect("Failed to execute tasklist");
|
||||||
|
|
||||||
let output_str = String::from_utf8_lossy(&output.stdout);
|
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 {
|
fn get_appdata_dir() -> std::path::PathBuf {
|
||||||
let exe_path = std::env::current_exe().expect("Failed to get executable path");
|
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 = 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()
|
std::path::Path::new(&format!("{}/", drive)).to_path_buf()
|
||||||
} else {
|
} else {
|
||||||
std::path::Path::new("C:/").to_path_buf()
|
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 {
|
loop {
|
||||||
// 使用 tasklist 命令检查进程是否存在
|
// 使用 tasklist 命令检查进程是否存在,使用 CSV 格式以便更精确地匹配
|
||||||
let output = Command::new("tasklist")
|
let output = Command::new("tasklist")
|
||||||
.args(["/FI", &format!("IMAGENAME eq {}", process_name)])
|
.args(["/FI", &format!("IMAGENAME eq {}", process_name), "/FO", "CSV"])
|
||||||
.output()
|
.output()
|
||||||
.expect("Failed to execute tasklist");
|
.expect("Failed to execute tasklist");
|
||||||
|
|
||||||
let output_str = String::from_utf8_lossy(&output.stdout);
|
let output_str = String::from_utf8_lossy(&output.stdout);
|
||||||
if !output_str.contains(process_name) {
|
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;
|
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 毫秒后再次检查
|
// 等待 100 毫秒后再次检查
|
||||||
sleep(Duration::from_millis(100));
|
sleep(Duration::from_millis(100));
|
||||||
|
|||||||
Reference in New Issue
Block a user