Skip to main content

user_startup/utils/
windows.rs

1use std::{
2    fs::File,
3    os::windows::process::CommandExt,
4    path::{Path, PathBuf},
5    process::Command,
6    sync::LazyLock as Lazy,
7};
8
9use super::parse_command;
10
11const CREATE_NO_WINDOW: u32 = 0x08000000;
12
13pub static CONFIG_PATH: Lazy<PathBuf> = Lazy::new(|| {
14    dirs::home_dir()
15        .expect("Could not find home directory")
16        .join("AppData")
17        .join("Roaming")
18        .join("Microsoft")
19        .join("Windows")
20        .join("Start Menu")
21        .join("Programs")
22        .join("Startup")
23});
24
25pub const COMMENT_PREFIX: &str = ":: ";
26
27pub fn comment(s: &str) -> String {
28    format!("{COMMENT_PREFIX}{s}")
29}
30
31pub const OPEN_COMMAND: &str = "explorer";
32
33pub const FILE_EXT: &str = ".cmd";
34
35fn escape_quotes(s: impl AsRef<str>) -> String {
36    s.as_ref().replace("\"", "^\"")
37}
38
39pub fn format(cmd: &str, _: Option<&str>, stdout: Option<&str>, stderr: Option<&str>) -> String {
40    format!(
41        r#"{prefixed_cmd}
42"{self_bin}" run "{cmd}" {stdout} {stderr}
43"#,
44        self_bin = std::env::current_exe()
45            .expect("Failed to get current executable path")
46            .display(),
47        prefixed_cmd = comment(cmd),
48        cmd = escape_quotes(cmd),
49        stdout = stdout.map_or(String::new(), |s| format!("--stdout {s}")),
50        stderr = stderr.map_or(String::new(), |s| format!("--stderr {s}"))
51    )
52}
53
54/// Run a command with NO_WINDOW.
55pub fn run_no_window(
56    cmd: impl AsRef<str>,
57    stdout: Option<impl AsRef<Path>>,
58    stderr: Option<impl AsRef<Path>>,
59) -> std::io::Result<()> {
60    let (bin, rest) = parse_command(cmd);
61    let mut command = Command::new(bin);
62    command.creation_flags(CREATE_NO_WINDOW).raw_arg(rest);
63    if let Some(stdout) = stdout {
64        let f = File::create(stdout)?;
65        command.stdout(f);
66    }
67    if let Some(stderr) = stderr {
68        let f = File::create(stderr)?;
69        command.stderr(f);
70    }
71    command.spawn()?;
72    Ok(())
73}