/** * Command utilities for hiding console windows in production builds * * This module provides utilities to configure std::process::Command instances * to hide console windows on Windows in production builds, preventing the * flash of command prompt windows when executing external processes. */ use std::process::Command; // Windows-specific imports for hiding console window #[cfg(target_os = "windows")] use std::os::windows::process::CommandExt; // Windows process creation flags #[cfg(target_os = "windows")] const CREATE_NO_WINDOW: u32 = 0x08000000; /// Configure a Command to hide console window in production builds on Windows /// /// This function applies the CREATE_NO_WINDOW flag to prevent console window /// flashing when spawning processes from a GUI application. The console window /// is only hidden in release builds to preserve debugging capabilities during /// development. /// /// # Arguments /// * `cmd` - Mutable reference to the Command to configure /// /// # Example /// ```rust /// use std::process::Command; /// use crate::command_utils::configure_no_window; /// /// let mut cmd = Command::new("python"); /// configure_no_window(&mut cmd); /// let output = cmd.output(); /// ``` pub fn configure_no_window(cmd: &mut Command) { #[cfg(target_os = "windows")] { // Only hide console window in release builds // In debug builds, keep console visible for debugging #[cfg(not(debug_assertions))] { cmd.creation_flags(CREATE_NO_WINDOW); println!("Console window hidden for release build"); } #[cfg(debug_assertions)] { println!("Console window visible for debug build"); } } // On non-Windows platforms, this function does nothing #[cfg(not(target_os = "windows"))] { // No-op on non-Windows platforms let _ = cmd; // Suppress unused variable warning } } /// Create a new Command with console window hiding configured /// /// This is a convenience function that creates a new Command and immediately /// configures it to hide console windows in production builds. /// /// # Arguments /// * `program` - The program to execute /// /// # Returns /// A configured Command instance /// /// # Example /// ```rust /// use crate::command_utils::create_hidden_command; /// /// let mut cmd = create_hidden_command("python"); /// cmd.args(&["-c", "print('Hello, World!')"]); /// let output = cmd.output(); /// ``` pub fn create_hidden_command>(program: S) -> Command { let mut cmd = Command::new(program); configure_no_window(&mut cmd); cmd } /// Configure a Command for Python execution with console window hiding /// /// This function configures a Command specifically for Python execution, /// including proper encoding setup and console window hiding. /// /// # Arguments /// * `cmd` - Mutable reference to the Command to configure /// * `project_root` - The working directory for the command /// * `args` - Command line arguments /// /// # Example /// ```rust /// use std::process::Command; /// use std::path::Path; /// use crate::command_utils::configure_python_command; /// /// let mut cmd = Command::new("python"); /// let args = vec!["-c".to_string(), "print('Hello')".to_string()]; /// configure_python_command(&mut cmd, Path::new("."), &args); /// ``` pub fn configure_python_command(cmd: &mut Command, project_root: &std::path::Path, args: &[String]) { cmd.current_dir(project_root); cmd.args(args); cmd.stdout(std::process::Stdio::piped()); cmd.stderr(std::process::Stdio::piped()); // Set environment variables for consistent encoding cmd.env("PYTHONIOENCODING", "utf-8"); cmd.env("PYTHONUNBUFFERED", "1"); // Platform-specific configurations if cfg!(target_os = "windows") { cmd.env("PYTHONUTF8", "1"); } // Configure console window hiding configure_no_window(cmd); } /// Configure a Command for system operations (file/folder opening) /// /// This function configures a Command for system operations like opening /// files or folders, with appropriate console window hiding. /// /// # Arguments /// * `cmd` - Mutable reference to the Command to configure /// /// # Example /// ```rust /// use std::process::Command; /// use crate::command_utils::configure_system_command; /// /// let mut cmd = Command::new("explorer"); /// cmd.arg("C:\\"); /// configure_system_command(&mut cmd); /// ``` pub fn configure_system_command(cmd: &mut Command) { // Configure console window hiding for system commands configure_no_window(cmd); } #[cfg(test)] mod tests { use super::*; use std::process::Command; #[test] fn test_configure_no_window() { let mut cmd = Command::new("echo"); configure_no_window(&mut cmd); // Test should not panic } #[test] fn test_create_hidden_command() { let cmd = create_hidden_command("echo"); // Test should not panic and should return a Command assert_eq!(cmd.get_program(), "echo"); } #[test] fn test_configure_python_command() { let mut cmd = Command::new("python"); let args = vec!["-c".to_string(), "print('test')".to_string()]; configure_python_command(&mut cmd, std::path::Path::new("."), &args); // Test should not panic } #[test] fn test_configure_system_command() { let mut cmd = Command::new("echo"); configure_system_command(&mut cmd); // Test should not panic } } /// Utility macro for creating a hidden command with arguments /// /// This macro provides a convenient way to create and configure a Command /// with console window hiding in a single expression. /// /// # Example /// ```rust /// use crate::command_utils::hidden_command; /// /// let output = hidden_command!("python", "-c", "print('Hello')").output(); /// ``` #[macro_export] macro_rules! hidden_command { ($program:expr $(, $arg:expr)*) => { { let mut cmd = $crate::command_utils::create_hidden_command($program); $(cmd.arg($arg);)* cmd } }; } // Note: The hidden_command macro is automatically available when this module is imported