mxivideo/src-tauri/src/command_utils.rs

207 lines
6.1 KiB
Rust

/**
* 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<S: AsRef<std::ffi::OsStr>>(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