slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
16.81k stars 553 forks source link

document how to prevent a console to open on Windows #3235

Open asuper0 opened 1 year ago

asuper0 commented 1 year ago

We need to add documentation for windows_subsystem attribute in our rust documentation. See #1190 And also how to keep log messages when wanted.

Original:

How to keep output message in console, but not to open a console window when run the app?

I disable the console window with the solution in #1190 . However, I use clap to let my app got some cli parameters and print help message. The code #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] totally disable all print info. Is there any solution to keep the print info when I'm in a console, but not to open a new one if not?

tronical commented 1 year ago

Thanks for reporting this. When you write "disable all print info", do you mean for example the output of clap when you run with --help? Or do you mean your own calls to say eprintln!?

ogoffart commented 1 year ago

I don't know the answer to this problem, but looking on the internet, it seems you may get along with winapi::um::wincon::AttachConsole https://stackoverflow.com/questions/64346513/how-do-i-have-a-hidden-console-when-using-windows-subsystem

We should document the windows_subsystem trick in our rust documentation. Please let us know what you tried and if you found something that worked for you.

asuper0 commented 1 year ago

Thanks for reporting this. When you write "disable all print info", do you mean for example the output of clap when you run with --help? Or do you mean your own calls to say eprintln!?

Yes, both cargo run -- --help and println! can output nothing. I didn't try eprintln! till now.

asuper0 commented 1 year ago

I don't know the answer to this problem, but looking on the internet, it seems you may get along with winapi::um::wincon::AttachConsole https://stackoverflow.com/questions/64346513/how-do-i-have-a-hidden-console-when-using-windows-subsystem

Ok, I'm glad to try it. Will do this next week since I'm on vacation.

asuper0 commented 1 year ago

Hi, I have tested the winapi::um::wincon::AttachConsole() method, it works.

#![windows_subsystem = "windows")]
// I don't use the #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
// If you want to use it, you may disable code below in debug mode

fn main() {
    unsafe {
        winapi::um::wincon::AttachConsole(0xFFFFFFFF);
    }

    // other code ...

    unsafe {
        winapi::um::wincon::FreeConsole();
    }
}

However, it's not perfect because the cursor of console is not correct. Look pictures below

attach1 The console when app running attach2 The console when app exit, and type some command attach3 Press enter

As you can see, the console's cursor don't know the output content, so it keeps the location when the ./test.exe command is executed.

asuper0 commented 1 year ago

I'd prefer another solution: don't set windows_subsystem but detach console when you run the app from explorer.

fn get_parent_process_name() -> Option<String> {
    use sysinfo::{ProcessExt, RefreshKind, System, SystemExt};

    let sys =
        System::new_with_specifics(RefreshKind::new().with_processes(ProcessRefreshKind::new()));

    if let Some(process) = sys.process(sysinfo::get_current_pid().unwrap()) {
        if let Some(parent_pid) = process.parent() {
            if let Some(parent_process) = sys.process(parent_pid) {
                return Some(parent_process.name().to_lowercase());
            }
        }
    }

    None
}

fn main() {
    let parent_process = get_parent_process_name();
    let run_without_console = match &parent_process {
        Some(s) if s == "explorer.exe" => true,
        _ => false,
    };

    if run_without_console {
        unsafe {
            winapi::um::wincon::FreeConsole();
        }
    }
}

Notice this code don't use #![windows_subsystem = "windows")]. It works well when you run it from console. When run it run explorer, a new console window would show and disappear, I think it's ok.

hunger commented 1 year ago

Can we do something in Slint to help with your use case or can we close this issue now?

ogoffart commented 1 year ago

We need to document this in a "platform specific considerations" page or something in our rust documentation. Cf #1190 which was closed before we actually documented the problem.

asuper0 commented 1 year ago

The problem is solved for me. However, it's better to add something to the document, as @ogoffart has mentioned.

ogoffart commented 7 months ago

Same with C++ https://github.com/slint-ui/slint/issues/1190

ansarizafar commented 7 months ago

How we can solve this issue with Slint-UI Javascript?

tronical commented 7 months ago

For each programming language we should have a chapter that explains - on a per-platform basis - what the necessary steps are to prepare the application for deployment. This includes console subsystem de-selection on Windows.

sedan-cell commented 3 months ago

#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] prevents the console from showing but also --help messages from clap from being available to a user.