Merge branch 'master' of ssh://gitea.bowongai.com:221/bowong/mxivideo

This commit is contained in:
imeepos 2025-07-11 13:58:28 +08:00
commit 5d35aab1ab
6 changed files with 224 additions and 73 deletions

View File

@ -0,0 +1,206 @@
/**
* 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

View File

@ -1,14 +1,7 @@
use serde::Deserialize;
use std::process::Command;
use crate::python_executor::execute_python_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;
use crate::command_utils::configure_no_window;
#[derive(Debug, Deserialize)]
pub struct AIVideoRequest {
@ -121,14 +114,8 @@ pub async fn test_ai_video_environment(_app: tauri::AppHandle) -> Result<String,
cmd.current_dir(&project_root)
.args(&["-c", "import sys; print(f'Python {sys.version}'); import requests; print('requests OK'); import PIL; print('PIL OK')"]);
// Hide console window in release builds
#[cfg(target_os = "windows")]
{
#[cfg(not(debug_assertions))]
{
cmd.creation_flags(CREATE_NO_WINDOW);
}
}
// Configure console window hiding
configure_no_window(&mut cmd);
let output = cmd.output();

View File

@ -1,3 +1,5 @@
use crate::command_utils::configure_system_command;
#[tauri::command]
pub async fn select_image_file(app: tauri::AppHandle) -> Result<String, String> {
use tauri_plugin_dialog::{DialogExt};
@ -52,10 +54,14 @@ pub async fn open_folder(folder_path: String) -> Result<String, String> {
#[cfg(target_os = "windows")]
{
use std::process::Command;
let result = Command::new("explorer")
.arg(&folder_path)
.spawn();
let mut cmd = Command::new("explorer");
cmd.arg(&folder_path);
// Configure console window hiding
configure_system_command(&mut cmd);
let result = cmd.spawn();
match result {
Ok(_) => Ok(format!("Opened folder: {}", folder_path)),
Err(e) => Err(format!("Failed to open folder: {}", e))

View File

@ -1,14 +1,7 @@
use serde::{Deserialize, Serialize};
use tauri::{command, AppHandle};
use crate::python_executor::execute_python_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;
use crate::command_utils::configure_system_command;
#[derive(Debug, Serialize, Deserialize)]
pub struct ProjectInfo {
@ -82,11 +75,8 @@ pub async fn open_file_in_system(file_path: String) -> Result<(), String> {
let mut cmd = std::process::Command::new("cmd");
cmd.args(["/C", "start", "", &file_path]);
// Hide console window in release builds
#[cfg(not(debug_assertions))]
{
cmd.creation_flags(CREATE_NO_WINDOW);
}
// Configure console window hiding
configure_system_command(&mut cmd);
cmd.spawn()
.map_err(|e| format!("Failed to open file: {}", e))?;

View File

@ -1,6 +1,7 @@
mod commands;
mod python_executor;
mod macros;
mod command_utils;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {

View File

@ -6,46 +6,7 @@ use std::sync::{Arc, Mutex};
use std::sync::mpsc;
use serde::{Deserialize, Serialize};
use tauri::{AppHandle, Emitter};
// 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 for Python execution with proper console window handling
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");
// Hide console window in release builds to prevent flashing
// In debug builds, keep console visible for debugging
#[cfg(target_os = "windows")]
{
#[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");
}
}
}
}
use crate::command_utils::configure_python_command;
/// Generic progress information from Python processes
#[derive(Debug, Serialize, Deserialize, Clone)]