Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run Hidden (On Windows) #100

Open
collindutrow opened this issue Apr 14, 2023 · 6 comments
Open

Run Hidden (On Windows) #100

collindutrow opened this issue Apr 14, 2023 · 6 comments
Labels
help wanted Extra attention is needed

Comments

@collindutrow
Copy link

Normally running Rust applications with #![windows_subsystem = "windows"] effectively hides the console window.

It would be nice if there were some config for rust-script or an automated way to detect scripts containing this line and ensure that rust-script itself doesn't create a console window to run the application.

I feel this is important when running automated scripts from Task Scheduler or other scripts. And I think rust-script shouldn't necessarily be popping up a new console window each time when it's undesired that it does so. Since new windows are Focus grabbing and can interfere with other things you may be doing, it would be nice to have an official way around this.

@fornwall
Copy link
Owner

Thanks for reporting!

I don't know much about Windows myself.

What would be the drawback of rust-script having #![windows_subsystem = "windows"] (what happens in that case when rust-script is run from the console)? Created #101 if you want a branch to test with.

@fornwall fornwall added the help wanted Extra attention is needed label Apr 14, 2023
@collindutrow
Copy link
Author

collindutrow commented Apr 15, 2023

Well, the normal action of a terminal application being run from the GUI on Windows is to open a console and close the console immediately when the application completes. So for most console applications on Windows, this means the console will flash on the screen and disappear a second later if you tried to double-click their binaries from the file explorer.

In Rust a way around this that I know is to specify using the windows subsystem (typically used for GUI applications under Rust to make the console not show), and then reattach the console allowing console output to still display if run from Windows command prompt but nothing to show if run directly from explorer. This might be the most appropriate approach for rust-script on Windows.

Here's a working example. Maybe someone else can comment on the efficacy or shortcomings of this method but I've never had an issue with it. (I'm running Windows 11 just to be clear)

cargo.toml

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["wincon"] }

main.rs

#![windows_subsystem = "windows"]
fn main() {
    #[cfg(target_os = "windows")]
    {
        use winapi::um::wincon::{AttachConsole, ATTACH_PARENT_PROCESS};

        unsafe {
            AttachConsole(ATTACH_PARENT_PROCESS);
        }
    }

    println!("Hello, world!");
}

@collindutrow collindutrow reopened this Apr 15, 2023
@fornwall
Copy link
Owner

fornwall commented Apr 16, 2023

@wintersnare Thanks a lot!

I added AttachConsole as you show to #101 (the windows-subsystem branch), so please test it out if you can!

@collindutrow
Copy link
Author

collindutrow commented Apr 18, 2023

20230417190129.mp4

I think windows_subsystem = "windows" may not be appropriate for the main rust-script executable.
It works great when running from the GUI, but when running Rust scripts from the console even ones that do not define windows_subsystem = "windows" they cause the console to hang until the user presses Enter. I'm not sure of a way around this.

I've attached a video demonstrating this. The .ers does not have windows_subsystem = "windows" defined anywhere.

[Test 1] Using the executable included with the crate, it works normally from the console. [Test 2] The second test is run from the #101 build. [Test 3] The third test is executing the compiled script executable directly from the rust-script cache directory.

Test 1 and 3 work as expected.
Test 2 'hangs' (even though the process no longer exists) until I press enter and echo __DONE__ is launched asynchronously as when running rust-script (experimental) it's returning immediately as it's not a true console application.

In my use cases windows_subsystem = "windows" hasn't been an issue as I'm not using it for console output, but looking at it from this perspective it will definitely produce unexpected results for people.

Python on Windows handles this by providing 2 executables. python.exe (console) and pythonw.exe (windows) and on Windows .py is associated with python.exe and .pyw is associated with pythonw.exe. Any script where you want to avoid a console from popping up you just change the extension to .pyw

So maybe inspiration can be taken from that.

@fornwall
Copy link
Owner

@wintersnare Thanks for all this helpful information!

Perhaps the python way - distributing two binaries, and using two file extensions - is the best way then?

@collindutrow
Copy link
Author

@fornwall Yes, I think this would be the best way for Windows environments.

I was thinking though that in the event of an error, it should probably write a unique .log file to the user's temp directory and automatically open it for the user to still be able to read the output.

The environment variable in Windows for the user's temp directory is TEMP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants