Skip to content
This repository was archived by the owner on Jul 27, 2023. It is now read-only.

Commit 1fbff65

Browse files
committed
Attach a console if available
If we run within a console environment (e.g. from powershell), allocate attach the console, so that we can easily write to stdout/stderr.
1 parent c9f04b3 commit 1fbff65

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

xi-win-shell/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ time = "0.1.39"
1515

1616
[dependencies.winapi]
1717
version = "0.3.6"
18-
features = ["d2d1_1", "dwrite", "winbase", "libloaderapi", "errhandlingapi", "winuser", "shellscalingapi", "shobjidl", "combaseapi", "synchapi", "dxgi1_3", "dcomp", "d3d11", "dwmapi"]
18+
features = ["d2d1_1", "dwrite", "winbase", "libloaderapi", "errhandlingapi", "winuser", "shellscalingapi", "shobjidl", "combaseapi", "synchapi", "dxgi1_3", "dcomp", "d3d11", "dwmapi", "wincon", "fileapi", "processenv", "winbase"]

xi-win-shell/src/util.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,26 @@
1919
2020
use std::ffi::{OsStr, OsString, CString};
2121
use std::fmt;
22+
use std::mem;
2223
use std::os::windows::ffi::{OsStrExt, OsStringExt};
24+
use std::ptr;
2325
use std::slice;
24-
use std::mem;
25-
2626
use winapi::ctypes::c_void;
2727
use winapi::shared::guiddef::REFIID;
2828
use winapi::shared::minwindef::*;
2929
use winapi::shared::ntdef::*;
3030
use winapi::shared::windef::*;
3131
use winapi::shared::winerror::SUCCEEDED;
32+
use winapi::um::fileapi::*;
33+
use winapi::um::handleapi::*;
3234
use winapi::um::libloaderapi::*;
35+
use winapi::um::processenv::*;
3336
use winapi::um::shellscalingapi::*;
3437
use winapi::um::unknwnbase::IUnknown;
38+
use winapi::um::winbase::*;
39+
use winapi::um::wincon::*;
40+
// This needs to be explicit, otherwise HRESULT will conflict
41+
use winapi::um::winnt::{GENERIC_READ, GENERIC_WRITE, FILE_SHARE_WRITE};
3542

3643
use direct2d::enums::DrawTextOptions;
3744

@@ -227,6 +234,7 @@ lazy_static! {
227234

228235
/// Initialize the app. At the moment, this is mostly needed for hi-dpi.
229236
pub fn init() {
237+
attach_console();
230238
if let Some(func) = OPTIONAL_FUNCTIONS.SetProcessDpiAwareness {
231239
// This function is only supported on windows 10
232240
unsafe {
@@ -257,3 +265,37 @@ macro_rules! accel {
257265
]
258266
}
259267
}
268+
269+
/// Attach the process to the console of the parent process. This allows xi-win to
270+
/// correctly print to a console when run from powershell or cmd.
271+
/// If no console is available, allocate a new console.
272+
fn attach_console() {
273+
unsafe {
274+
let stdout = GetStdHandle(STD_OUTPUT_HANDLE);
275+
if stdout != INVALID_HANDLE_VALUE && GetFileType(stdout) != FILE_TYPE_UNKNOWN {
276+
// We already have a perfectly valid stdout and must not attach.
277+
// This happens, for example in MingW consoles like git bash.
278+
return;
279+
}
280+
281+
if AttachConsole(ATTACH_PARENT_PROCESS) > 0 {
282+
let chnd = CreateFileA(
283+
CString::new("CONOUT$").unwrap().as_ptr(),
284+
GENERIC_READ | GENERIC_WRITE,
285+
FILE_SHARE_WRITE,
286+
ptr::null_mut(),
287+
OPEN_EXISTING,
288+
0,
289+
ptr::null_mut());
290+
291+
if chnd == INVALID_HANDLE_VALUE {
292+
// CreateFileA failed.
293+
return;
294+
}
295+
296+
SetStdHandle(STD_OUTPUT_HANDLE, chnd);
297+
SetStdHandle(STD_ERROR_HANDLE, chnd);
298+
}
299+
}
300+
}
301+

0 commit comments

Comments
 (0)