hatchery_node/
windows_process.rs1pub const CREATE_NO_WINDOW: u32 = 0x0800_0000;
9pub const DETACHED_PROCESS: u32 = 0x0000_0008;
11pub const CREATE_NEW_PROCESS_GROUP: u32 = 0x0000_0200;
13
14pub const HEADLESS_SPAWN_FLAGS: u32 = CREATE_NO_WINDOW | DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
16
17pub fn hide_console(command: &mut std::process::Command) {
21 set_creation_flags(command, CREATE_NO_WINDOW);
22}
23
24pub fn hide_console_tokio(command: &mut tokio::process::Command) {
26 #[cfg(windows)]
27 {
28 hide_console(command.as_std_mut());
29 }
30 #[cfg(not(windows))]
31 {
32 let _ = command;
33 }
34}
35
36pub fn set_creation_flags(command: &mut std::process::Command, flags: u32) {
38 #[cfg(windows)]
39 {
40 use std::os::windows::process::CommandExt;
41 command.creation_flags(flags);
43 }
44 #[cfg(not(windows))]
45 {
46 let _ = (command, flags);
47 }
48}
49
50pub fn hide_console_detached(command: &mut std::process::Command) {
52 set_creation_flags(command, HEADLESS_SPAWN_FLAGS);
53}
54
55pub fn free_console() {
57 #[cfg(windows)]
58 {
59 unsafe {
61 let _ = windows_sys::Win32::System::Console::FreeConsole();
62 }
63 }
64}
65
66pub fn ignore_console_close_events() {
70 #[cfg(windows)]
71 {
72 unsafe extern "system" fn handler(ctrl: u32) -> i32 {
73 use windows_sys::Win32::System::Console::{
74 CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_EVENT,
75 };
76 match ctrl {
77 CTRL_CLOSE_EVENT | CTRL_LOGOFF_EVENT | CTRL_SHUTDOWN_EVENT => 1, _ => 0,
79 }
80 }
81 unsafe {
82 let _ = windows_sys::Win32::System::Console::SetConsoleCtrlHandler(Some(handler), 1);
83 }
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn hide_console_keeps_program_and_args() {
93 let mut c = std::process::Command::new("prog");
94 c.arg("a").arg("b");
95 hide_console(&mut c);
96 assert_eq!(c.get_program(), std::ffi::OsStr::new("prog"));
97 assert_eq!(c.get_args().collect::<Vec<_>>(), ["a", "b"]);
98 }
99
100 #[test]
101 fn create_no_window_constant() {
102 assert_eq!(CREATE_NO_WINDOW, 0x0800_0000);
103 assert_eq!(DETACHED_PROCESS, 0x0000_0008);
104 assert_ne!(HEADLESS_SPAWN_FLAGS & CREATE_NO_WINDOW, 0);
105 }
106}