From 38c969db1b39badf9d58c72dc954bb25c954d30e Mon Sep 17 00:00:00 2001 From: mtkennerly Date: Tue, 19 Mar 2024 17:40:59 -0400 Subject: [PATCH] test --- src/main.rs | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/main.rs b/src/main.rs index 0361d25..be978fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,6 +47,72 @@ fn prepare_logging() -> Result`, +/// but that is not yet widely available: +/// https://github.com/microsoft/terminal/blob/5383cb3a1bb8095e214f7d4da085ea4646db8868/doc/specs/%237335%20-%20Console%20Allocation%20Policy.md +/// +/// ## Considerations +/// The current approach is to let the console appear and then immediately `FreeConsole`. +/// Previously, Windows Terminal wouldn't remove the console in that case, +/// but that has been fixed: https://github.com/microsoft/terminal/issues/16174 +/// +/// There was also an issue where asynchronous Rclone commands would fail to spawn +/// ("The request is not supported (os error 50)"), +/// but that has been solved by resetting the standard device handles: +/// https://github.com/rust-lang/rust/issues/113277 +#[cfg(target_os = "windows")] +unsafe fn detach_console() { + use winapi::um::{ + processenv::SetStdHandle, + winbase::{STD_ERROR_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE}, + wincon::FreeConsole, + }; + + if FreeConsole() == 0 { + eprintln!("Unable to detach the console"); + std::process::exit(1); + } + if SetStdHandle(STD_INPUT_HANDLE, std::ptr::null_mut()) == 0 { + eprintln!("Unable to reset stdin handle"); + std::process::exit(1); + } + if SetStdHandle(STD_OUTPUT_HANDLE, std::ptr::null_mut()) == 0 { + eprintln!("Unable to reset stdout handle"); + std::process::exit(1); + } + if SetStdHandle(STD_ERROR_HANDLE, std::ptr::null_mut()) == 0 { + eprintln!("Unable to reset stderr handle"); + std::process::exit(1); + } +} + fn main() { let args = cli::parse(); if let Some(config_dir) = args.config.as_deref() { @@ -54,6 +120,14 @@ fn main() { } match args.sub { None => { + #[cfg(target_os = "windows")] + if std::env::var(crate::prelude::ENV_DEBUG).is_err() { + unsafe { + detach_console(); + } + } + + // We must do this after detaching the console, or else it will still be present, somehow. #[allow(unused)] let logger = prepare_logging();