60 lines
2.0 KiB
Rust
60 lines
2.0 KiB
Rust
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 shim = match Mirror::load() {
|
||
Ok(v) => v,
|
||
Err(e) => {
|
||
eprintln!("加载代理(shim)配置时发生错误: {}", e);
|
||
exit(EXIT_FAILED_LOAD_SHIM);
|
||
}
|
||
};
|
||
// 构建 Command:复用 ShimConfig::to_command(含 args/env 注入),避免重复逻辑
|
||
let mut cmd = shim.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 = shim.args.clone();
|
||
args.extend_from_slice(&calling_args);
|
||
|
||
exit(execute_elevated(&shim.target, &args, Some(&shim.env)))
|
||
}
|
||
Err(e) => {
|
||
eprintln!(
|
||
"启动目标程序 [{}] 时发生错误: {}",
|
||
shim.target.to_string_lossy(),
|
||
e
|
||
);
|
||
exit(EXIT_FAILED_SPAWN_PROG);
|
||
}
|
||
};
|
||
// 5. 等待子进程退出
|
||
let status = match child.wait() {
|
||
Ok(v) => v,
|
||
Err(e) => {
|
||
eprintln!(
|
||
"等待目标程序 [{}] 执行完毕时发生错误: {}",
|
||
shim.target.to_string_lossy(),
|
||
e
|
||
);
|
||
exit(EXIT_FAILED_WAIT_PROG);
|
||
}
|
||
};
|
||
exit(status.code().unwrap_or(EXIT_PROG_TERMINATED))
|
||
}
|