fix(core): 所有子进程统一走 platform::child::quiet + 角色守卫(M213)
GUI 父进程(PE Subsystem = 2)spawn 控制台子进程时,Windows 会为子进程新建一块
控制台——桌面上就是「黑框闪一下」。改前 crates/core/src 有 21 处 Command::new,
只有 tree_kill 那一处带了 CREATE_NO_WINDOW,于是探 N 个 JDK 就闪 N 次 java -version。
- 新增 crates/core/src/platform/child.rs:唯一构造器 quiet(program),Windows 上统一
.creation_flags(CREATE_NO_WINDOW),其它平台原样返回。tree_kill 里那份就地合并进来,
不再保留第二份常量。
- 20 处 spawn 全部改走它(region_system / java{discover,manual,probe,proc,termux} /
addon exec / platform{linux_caps,macos_version,theme_probe,vk_probe,windows_version,
wallpaper/io})。
- launch/process.rs 零改动:游戏进程要 CREATE_NEW_PROCESS_GROUP 撑 taskkill /T,
带不带控制台窗口是产品决定。
- crates/core/tests/child_quiet.rs:按角色判「有没有绕开构造器」的守卫,外加构造器
本身的 4 条行为用例。三条变异(裸 Command::new / 别名 Spawn::new / 删掉 creation_flags)
都实测变红并已还原。
This commit is contained in:
1 parent
bb8be87c8f
commit
40a296471d
17 files changed
+417
-39
No files matched your search
@@ -28,7 +28,8 @@
|
||||
//! 的实际停止流程以“进程是否真的消失”为准(`try_wait` 轮询),本模块只提供发送动作。
|
||||
|
||||
use std::io;
|
||||
use std::process::Command;
|
||||
|
||||
use crate::platform::child::quiet;
|
||||
|
||||
/// 温和关闭(Windows 无 `/F`;POSIX `SIGTERM`)。
|
||||
pub fn terminate(pid: u32) -> io::Result<()> {
|
||||
@@ -100,7 +101,7 @@ fn pgid_of(pid: u32) -> Option<u32> {
|
||||
|
||||
#[cfg(all(unix, not(target_os = "linux")))]
|
||||
fn pgid_of(pid: u32) -> Option<u32> {
|
||||
let output = Command::new("ps")
|
||||
let output = quiet("ps")
|
||||
.args(["-o", "pgid=", "-p", &pid.to_string()])
|
||||
.output()
|
||||
.ok()?;
|
||||
@@ -113,18 +114,14 @@ fn pgid_of(pid: u32) -> Option<u32> {
|
||||
#[cfg(windows)]
|
||||
mod imp {
|
||||
use super::*;
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
/// 不弹控制台窗口(否则 kill 子进程会闪一个黑框)。
|
||||
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
|
||||
|
||||
pub(super) fn signal(pid: u32, force: bool) -> io::Result<()> {
|
||||
let mut command = Command::new("taskkill");
|
||||
// `CREATE_NO_WINDOW` 由 `platform::child::quiet` 统一带(否则 kill 子进程会闪一个黑框)。
|
||||
let mut command = quiet("taskkill");
|
||||
command.arg("/PID").arg(pid.to_string()).arg("/T");
|
||||
if force {
|
||||
command.arg("/F");
|
||||
}
|
||||
command.creation_flags(CREATE_NO_WINDOW);
|
||||
let status = command
|
||||
.stdout(std::process::Stdio::null())
|
||||
.stderr(std::process::Stdio::null())
|
||||
@@ -168,7 +165,7 @@ mod imp {
|
||||
/// `kill` 不存在时给**明确**错误而不是静默失败:否则调用方只会看到“进程仍在运行”,
|
||||
/// 排查方向会被带偏(M48 之前的红灯就是这么来的)。
|
||||
fn run_kill(flag: &str, args: &[&str]) -> io::Result<bool> {
|
||||
match Command::new("kill")
|
||||
match quiet("kill")
|
||||
.arg(flag)
|
||||
.args(args)
|
||||
.stdout(std::process::Stdio::null())
|
||||
|
||||
Reference in new issue
Block a user