fix(windows): hide conhost window spawned with core sidecar (#731)

The core binary is a console-subsystem .exe so `openhuman core run`
works correctly in a terminal. When the GUI shell (which is built with
`windows_subsystem = "windows"`) spawns it as a child without the
`CREATE_NO_WINDOW` creation flag, Windows allocates a fresh conhost
window that pops up on top of the app.

Apply `CREATE_NO_WINDOW` (0x08000000) at every site where the GUI
launches a core subprocess:

- `core_process.rs`: both sidecar spawn paths (`CoreRunMode::InProcess`
  fallback and `CoreRunMode::ChildProcess`).
- `lib.rs`: the short-lived `run_core_cli` used by `service_*_direct`
  commands.

Non-Windows builds get a no-op helper, so the cross-platform call sites
stay identical. Stdout/stderr piping for log forwarding is unaffected.
This commit is contained in:
CodeGhost21
2026-04-21 16:16:00 +05:30
committed by GitHub
parent 1792135aea
commit 63bc463c26
2 changed files with 24 additions and 0 deletions
+17
View File
@@ -25,6 +25,21 @@ fn apply_core_color_env(cmd: &mut Command) {
}
}
/// Hide the console window that Windows would otherwise allocate for the
/// core sidecar. The core binary is a console-subsystem executable so that
/// `openhuman core run` in a terminal behaves normally, but when the GUI
/// shell spawns it as a child a stray conhost window pops up on top of the
/// app. `CREATE_NO_WINDOW` suppresses that while leaving stdout/stderr
/// piping intact for our log forwarding.
#[cfg(windows)]
fn apply_core_no_window(cmd: &mut Command) {
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
cmd.creation_flags(CREATE_NO_WINDOW);
}
#[cfg(not(windows))]
fn apply_core_no_window(_cmd: &mut Command) {}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CoreRunMode {
InProcess,
@@ -142,6 +157,7 @@ impl CoreProcessHandle {
cmd
};
apply_core_color_env(&mut cmd);
apply_core_no_window(&mut cmd);
let child = cmd
.spawn()
.map_err(|e| format!("failed to spawn core process: {e}"))?;
@@ -180,6 +196,7 @@ impl CoreProcessHandle {
};
apply_core_color_env(&mut cmd);
apply_core_no_window(&mut cmd);
let child = cmd
.spawn()
.map_err(|e| format!("failed to spawn core process: {e}"))?;
+7
View File
@@ -222,6 +222,13 @@ async fn run_core_cli(args: Vec<String>) -> Result<String, String> {
}
cmd.args(&args);
#[cfg(windows)]
{
use std::os::windows::process::CommandExt;
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
cmd.creation_flags(CREATE_NO_WINDOW);
}
log::info!(
"[service-direct] running {:?} {}{}",
bin,