use mirror::sys::*; use mirror::Mirror; use std::{env, process::exit}; use tracing_subscriber::{fmt, EnvFilter}; fn main() { //初始化日志:输出到 stderr,避免污染 shim 子进程的 stdout fmt() .with_writer(std::io::stderr) .with_env_filter( EnvFilter::try_from_env("SHIM_LOG").unwrap_or_else(|_| EnvFilter::new("warn")), ) .init(); // 2. 注册 Windows 控制台信号 set_console_ctrl_handler(); // 3. 解析调用参数与代理 Shim 配置 let calling_args: Vec<_> = env::args_os().skip(1).collect(); let mr = match Mirror::new() { Ok(v) => v, Err(e) => { eprintln!("加载代理(shim)配置时发生错误: {}", e); exit(EXIT_FAILED_LOAD_SHIM); } }; // 构建 Command:复用 ShimConfig::to_command(含 args/env 注入),避免重复逻辑 let mut cmd = mr.to_command(&calling_args); let mut child = match cmd.spawn() { Ok(v) => v, Err(e) if e.raw_os_error() == Some(ERROR_ELEVATION_REQUIRED) => { // 提权回退时需要完整参数:配置默认参数 + 调用方透传参数 let mut args = mr.spec.args.clone(); args.extend_from_slice(&calling_args); exit(execute_elevated(&mr.spec.target, &args, Some(&mr.spec.env))) } Err(e) => { eprintln!( "启动目标程序 [{}] 时发生错误: {}", mr.spec.target.to_string_lossy(), e ); exit(EXIT_FAILED_SPAWN_PROG); } }; // 5. 等待子进程退出 let status = match child.wait() { Ok(v) => v, Err(e) => { eprintln!( "等待目标程序 [{}] 执行完毕时发生错误: {}", mr.spec.target.to_string_lossy(), e ); exit(EXIT_FAILED_WAIT_PROG); } }; exit(status.code().unwrap_or(EXIT_PROG_TERMINATED)) }