From e0b5dbde44e2e659c509b4cffb3eea813b3732f4 Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Sun, 21 Jan 2024 17:31:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=88=91=E5=86=B3=E5=AE=9A=E5=85=88init?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Cargo.lock | 32 ++++++++++++ Cargo.toml | 16 ++++++ src/config.rs | 83 +++++++++++++++++++++++++++++ src/main.rs | 41 +++++++++++++++ src/test.rs | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/win.rs | 10 ++++ 7 files changed, 325 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/config.rs create mode 100644 src/main.rs create mode 100644 src/test.rs create mode 100644 src/win.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..00f342a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,32 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "call" +version = "0.1.0" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..7572b7e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "call" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[profile.release] +# 最小体积优化 +opt-level = 'z' +lto = true +codegen-units = 1 + +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3" +features = ["winuser", "wincon", "processthreadsapi"] diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..ef89770 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,83 @@ +pub const HELP_MESSAGE: &str = r#"call [options] [--] [arguments] +Options: + --hide Hide console window (default) + --show Show console window + --chdir Change working directory to lib (default) + --chdir=xxx Change working directory to xxx + --dir=xxx Working directory is xxx + --bin=xxx Specify executable file + --config=xxx Specify configuration file + --help Print this help message +"#; + +pub struct Config { + pub show_console: bool, + pub chdir: Option, + pub bin: Option, + pub dir: Option, + pub config: Option, + pub bin_arg: String, +} + +impl Config { + pub fn from_cli() -> Option { + let mut show_console = false; + let mut chdir: Option = None; + let mut bin: Option = None; + let mut dir: Option = None; + let mut config: Option = None; + let mut bin_arg = "".to_string(); + // -- 表示后面的参数都是可执行文件的参数 + let args: Vec = std::env::args().collect(); + // 先检查有没有 --help + if args.contains(&"--help".to_string()) { + println!("{}", HELP_MESSAGE); + return None; + } + + let index = args.iter().position(|x| x == "--"); + if index.is_some() { + // 把后面的所有函数拼接一下, 作为可执行文件的参数 + for i in index.unwrap() + 1..args.len() { + bin_arg.push_str(&args[i]); + if i != args.len() - 1 { + bin_arg.push(' '); + } + } + } + // 先尝试获取指定的控制台参数 + // --hide 表示隐藏控制台 + // --show 表示显示控制台 + // --chdir 表示切换工作目录 + // --chdir=xxx 表示切换工作目录到xxx + // --dir=xxx 表示工作目录是xxx + // --bin=xxx 表示指定可执行文件 + // --config=xxx 表示指定配置文件 + // --help 输出上面这一堆东西 + for i in 1..args.len() { + if args[i] == "--" { + break; + } else if args[i] == "--hide" { + show_console = false; + } else if args[i] == "--show" { + show_console = true; + } else if args[i].starts_with("--chdir=") { + chdir = Some(args[i][8..].to_string()); + } else if args[i].starts_with("--dir=") { + dir = Some(args[i][6..].to_string()); + } else if args[i].starts_with("--bin=") { + bin = Some(args[i][6..].to_string()); + } else if args[i].starts_with("--config=") { + config = Some(args[i][9..].to_string()); + } + } + Some(Config { + show_console, + chdir, + bin, + dir, + config, + bin_arg, + }) + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ac271e6 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,41 @@ +#![windows_subsystem = "windows"] + +use std::process::Command; + +#[cfg(windows)] +mod win; +#[cfg(not(windows))] +compile_error!("This program only support windows! (这个程序只支持windows!) (截止 20240121 为止)"); + +mod config; + +pub const VERSION: &'static str = env!("CARGO_PKG_VERSION"); + +fn main() { + let config = config::Config::from_cli(); + if config.is_none() { + return; + } + let config = config.unwrap(); + if config.show_console { + win::show_window(); + } else { + win::hide_window(); + } + if config.chdir.is_some() { + std::env::set_current_dir(config.chdir.unwrap()).unwrap(); + } + if config.dir.is_some() { + std::env::set_current_dir(config.dir.unwrap()).unwrap(); + } + if config.config.is_some() { + std::env::set_current_dir(config.config.unwrap()).unwrap(); + } + if config.bin.is_some() { + let mut cmd = Command::new(config.bin.unwrap()); + if config.bin_arg.len() > 0 { + cmd.arg(config.bin_arg); + } + cmd.spawn().unwrap(); + } +} diff --git a/src/test.rs b/src/test.rs new file mode 100644 index 0000000..3522c02 --- /dev/null +++ b/src/test.rs @@ -0,0 +1,142 @@ +// #![windows_subsystem = "windows"] +use std::process::Command; + +fn hide_window() { + #[cfg(windows)] + unsafe { + attach_console(); + let _hwnd = winapi::um::winuser::GetForegroundWindow(); + let is_console: bool = winapi::um::wincon::GetConsoleWindow() != std::ptr::null_mut(); + if is_console { + println!("hide!"); + // winapi::um::winuser::ShowWindow(_hwnd, winapi::um::winuser::SW_HIDE); + // 使用 free console + winapi::um::wincon::FreeConsole(); + } else { + println!("show!"); + } + } +} + +fn show_window() { + #[cfg(windows)] + unsafe { + let _hwnd = winapi::um::winuser::GetForegroundWindow(); + winapi::um::winuser::ShowWindow(_hwnd, winapi::um::winuser::SW_SHOW); + } +} + +fn attach_console() { + #[cfg(windows)] + unsafe { + winapi::um::wincon::AttachConsole(winapi::um::wincon::ATTACH_PARENT_PROCESS); + } +} + +fn main() { + attach_console(); + println!("0.1.3"); + // 先尝试获取指定的控制台参数 + let args: Vec = std::env::args().collect(); + // --hide 表示隐藏控制台 + // --show 表示显示控制台 + // --chdir 表示切换工作目录 + // --chdir=xxx 表示切换工作目录到xxx + // --dir=xxx 表示工作目录是xxx + // --bin=xxx 表示指定可执行文件 + // --config=xxx 表示指定配置文件 + + let mut show_console = false; + let mut chdir: Option<&str> = None; + let mut bin: Option<&str> = None; + let mut dir: Option<&str> = None; + let mut config: Option<&str> = None; + let mut bin_arg = "".to_string(); + // -- 表示后面的参数都是可执行文件的参数 + let index = args.iter().position(|x| x == "--"); + if index.is_some() { + // 把后面的所有函数拼接一下, 作为可执行文件的参数 + for i in index.unwrap() + 1..args.len() { + bin_arg.push_str(&args[i]); + bin_arg.push_str(" "); + } + } + println!("bin_arg: {}", bin_arg); + + for arg in args.iter() { + if arg == "--" { + break; + } else if arg.starts_with("--hide") { + show_console = false; + } else if arg.starts_with("--show") { + show_console = true; + } else if arg == "--chdir" { + chdir = Some("lib"); + } else if arg.starts_with("--chdir=") { + chdir = Some(&arg[8..]); + } else if arg.starts_with("--bin=") { + bin = Some(&arg[6..]); + } else if arg.starts_with("--dir=") { + dir = Some(&arg[6..]); + } else if arg.starts_with("--config=") { + config = Some(&arg[9..]); + } + } + // 如果没有 --show 参数, 就隐藏控制台 + if show_console { + attach_console(); + } else { + hide_window(); + } + println!("chdir: {:?}", chdir); + println!("bin: {:?}", bin); + println!("dir: {:?}", dir); + println!("config: {:?}", config); + + // 隐藏控制台 + + // chdir 到 lib + if chdir.is_some() { + // 先检测指定的目录是否存在 + let path = std::path::Path::new(chdir.unwrap()); + if !path.exists() { + println!("WARN 指定的目录不存在"); + return; + } + // 切换工作目录 + std::env::set_current_dir(path).expect("切换工作目录失败"); + } + // 处理一下这堆参数 + // 拼接给定的 dir 和 bin + let mut bin_path = String::new(); + if dir.is_some() { + bin_path.push_str(dir.unwrap()); + bin_path.push_str("/"); + } else { + bin_path.push_str("./lib/"); + } + if bin.is_some() { + bin_path.push_str(bin.unwrap()); + } else { + bin_path.push_str("main"); + } + println!("bin_path: {}", bin_path); + // 判断可执行文件是否存在 + let path = std::path::Path::new(&bin_path); + if !path.exists() { + println!("WARN 指定的可执行文件不存在"); + } + // 判断可执行文件是否是文件 + if !path.is_file() { + println!("WARN 指定的可执行文件不是文件"); + } + // 执行! + let mut child = Command::new(&bin_path) + .arg(bin_arg) + .stdin(std::process::Stdio::inherit()) + .stdout(std::process::Stdio::inherit()) + .stderr(std::process::Stdio::inherit()) + .spawn() + .expect("执行失败"); + child.wait().expect("等待失败"); +} diff --git a/src/win.rs b/src/win.rs new file mode 100644 index 0000000..07c223c --- /dev/null +++ b/src/win.rs @@ -0,0 +1,10 @@ + + +pub fn hide_window () { + +} + +pub fn show_window () { + +} +