Build exe file for windows

Hello,

I am novice rust. I created a small program but I would like to get back the executable file to throw the just program by clicking above. I would have supposed that the executable file is in the build file. But when I open this the window opens one half-second. I looked everywhere on Google how to do! I do not find. Can you help me.

1 Like

If you are running the built file (target/{debug,release}/<executable name>.exe) then it will just flicker on the screen. If you want to run it and see the output (on the console) you need to either add some kind of pause at the end or run it in a terminal (cmd or power shell).

To be clear, the pause doesn't need to be in Rust. For example, if you put in this in the same directory as Cargo.toml (the filename can be whatever you want, I'm calling it run-release.bat for the sake of it):

cargo run --release
pause

That will run the release build and then pause (press any key to continue). You'll see output that way. You're better off opening a command prompt or power shell instance and working in there (at least in some way), but this will get you started.

1 Like

Yes I already use this method. I thought more in just of having the file .exe and just to click above. Because I saw certain rust applications just with the file exe and nothing else. How it is possible?

When you run cargo build [--release], the exe file will be in target\<debug|release>\app.exe, so you can copy it out.

Another tip, double clicking the exe would run it, but a console window tends to open as well. You can avoid it by adding #![windows_subsystem = "windows"] to the top of your main.rs file.

1 Like

Yes #![windows_subsystem = "windows"] work. But I would want to obtain my exe as in the example. Because I am obliged to make the command " cargo run --release " for run my program. I would just click above.
file

ohh, I misunderstood before. Is this correct: you want to be able to double click the app.exe, and that will open the console and interact with the user?

I haven't tried this, but perhaps using #![windows_subsystem = "console"], and where your program would normally end, you can do something like this:

println!("Press enter to exit");

let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer).ok(); // ignore the result
1 Like

No no sorry I badly expressed myself. I use Piston to create a window. But I can only open him by making " cargo run --release ". #![windows_subsystem = “windows”] good works to avoid having the console. However when I click the file .exe I have a white window which appears then disappears. And I do not know how to make so that I just have the file exe with the resources and to be able to launch it.

Oh gotcha, it's probably a working directory vs exe directory thing.
So somewhere in your code, you're probably loading resources (maybe fonts / images?). I'm guessing you're specifying the path to it, such as resources/my_image.png.

If you do that, then the application will look for "resources/my_image.png" from the directory you run the application from. I'm guessing your application's resources are in your crate directory which makes it work in development when you run cargo run, but you'd like it to work when you run the application anywhere, and the resources are beside the application.

// in development
my_app
|- resources
|    |- my_image.png  // for example
|
|- src/main.rs
|- target/debug/my_app.exe

// when you publish
anywhere
|- resources
|    |- my_image.png
|
|- my_app.exe

So to make the app find the resource, you probably want to do something like:

// Note: untested

use std::env;
use std::path::PathBuf;

fn load_resources() {
    // See <https://doc.rust-lang.org/stable/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates>
    let base_dir = option_env!("CARGO_MANIFEST_DIR").map_or_else(|| {
        let exe_path = env::current_exe().expect("Failed to get exe path");
        exe_path.parent.expect("Failed to get exe dir").to_path_buf()
    }, |crate_dir| {
        PathBuf::new(crate_dir);
    });

    let resources_dir = base_dir.join("resources");

    // for each resource
    load(resources_dir.join("my_image.png"));
}

Hope that helps

4 Likes

Oh god. Thank you so much! Everything works perfectly I understood now how's that work.