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 = DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
18
19pub fn hide_console(command: &mut std::process::Command) {
23 set_creation_flags(command, CREATE_NO_WINDOW);
24}
25
26pub fn hide_console_tokio(command: &mut tokio::process::Command) {
28 #[cfg(windows)]
29 {
30 hide_console(command.as_std_mut());
31 }
32 #[cfg(not(windows))]
33 {
34 let _ = command;
35 }
36}
37
38pub fn set_creation_flags(command: &mut std::process::Command, flags: u32) {
40 #[cfg(windows)]
41 {
42 use std::os::windows::process::CommandExt;
43 command.creation_flags(flags);
45 }
46 #[cfg(not(windows))]
47 {
48 let _ = (command, flags);
49 }
50}
51
52pub fn hide_console_detached(command: &mut std::process::Command) {
54 set_creation_flags(command, HEADLESS_SPAWN_FLAGS);
55}
56
57pub fn free_console() {
59 #[cfg(windows)]
60 {
61 unsafe {
63 let _ = windows_sys::Win32::System::Console::FreeConsole();
64 }
65 }
66}
67
68pub fn ignore_console_close_events() {
72 #[cfg(windows)]
73 {
74 unsafe extern "system" fn handler(ctrl: u32) -> i32 {
75 use windows_sys::Win32::System::Console::{
76 CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, CTRL_SHUTDOWN_EVENT,
77 };
78 match ctrl {
79 CTRL_CLOSE_EVENT | CTRL_LOGOFF_EVENT | CTRL_SHUTDOWN_EVENT => 1, _ => 0,
81 }
82 }
83 unsafe {
84 let _ = windows_sys::Win32::System::Console::SetConsoleCtrlHandler(Some(handler), 1);
85 }
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn hide_console_keeps_program_and_args() {
95 let mut c = std::process::Command::new("prog");
96 c.arg("a").arg("b");
97 hide_console(&mut c);
98 assert_eq!(c.get_program(), std::ffi::OsStr::new("prog"));
99 assert_eq!(c.get_args().collect::<Vec<_>>(), ["a", "b"]);
100 }
101
102 #[test]
103 fn create_no_window_constant() {
104 assert_eq!(CREATE_NO_WINDOW, 0x0800_0000);
105 assert_eq!(DETACHED_PROCESS, 0x0000_0008);
106 assert_eq!(HEADLESS_SPAWN_FLAGS, DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP);
107 }
108}