Rust 在release模式下编译 Windows exe去除黑窗口详细教程
- 一、处理步骤
- 1、修改Cargo.toml
- 2、修改main.rs
- 二、实现原理
- 1、`windows-subsystem = "windows"` 的作用
- 2、`cfg_attr` 与 `not(debug_assertions)` 的编译期判断
- 3、整体工作流程
- 4、小结
一、处理步骤
1、修改Cargo.toml
新增下面内容:
[[bin]]name="BatterySwitch"path="src/main.rs"windows-subsystem="windows"如下所示:
黄色框里面的内容要保持一样。
2、修改main.rs
在main.rs最前面新增#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
二、实现原理
1、windows-subsystem = "windows"的作用
在 Rust 中,默认情况下编译出的 Windows 可执行程序是控制台子系统程序。也就是说,当你双击运行它时,系统会先弹出一个黑色的命令行窗口,程序的所有标准输出(println!等)都会输出到这个控制台里。
对于像电池电量监控这种后台常驻型程序,我们并不希望每次启动都弹出一个黑框。因此需要在编译配置中声明程序属于Windows GUI 子系统:
- 在
Cargo.toml的[[bin]]段中写入windows-subsystem = "windows",告诉编译器:这个二进制程序不需要控制台窗口。 - 在
main.rs最前面写入#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")],它的含义是:仅在 release(发布)模式下隐藏控制台窗口,而在 debug(调试)模式下仍然保留控制台,方便开发时查看println!打印的日志。
两种写法效果等价,区别在于
Cargo.toml中的配置对 debug 和 release 都生效,而cfg_attr写法可以做到「调试时显示控制台、发布时隐藏控制台」,更利于开发调试。
2、cfg_attr与not(debug_assertions)的编译期判断
#![cfg_attr(条件, 属性)]是 Rust 的条件编译属性,它的执行时机在编译期,而不是程序运行期:
cfg_attr会根据括号内的条件,在编译时决定是否把第二个参数(即windows_subsystem = "windows")附加到当前 crate 上。not(debug_assertions)是一个内置的编译条件:当使用cargo build --release编译时,debug_assertions为false,取反后为true,于是该属性生效;当使用cargo build(默认 debug 模式)编译时,debug_assertions为true,取反后为false,该属性不生效。
因此,这一行代码的本质是:在发布版本中隐藏控制台窗口,在调试版本中保留控制台窗口,从而兼顾「用户体验」与「开发调试」两个需求。
3、整体工作流程
整个程序的实现原理可以概括为以下几个环节:
- 编译期:通过
Cargo.toml或cfg_attr声明 GUI 子系统,使最终生成的.exe在运行时不再弹出黑色控制台窗口。 - 运行期:程序启动后作为后台进程常驻系统,周期性读取电池电量信息。
- 交互期:当电量达到设定的阈值(如低电量或充满)时,程序通过系统通知或弹窗等方式提醒用户。
4、小结
通过以上配置,我们实现了两个目标:
- 用户侧:程序以无窗口的 GUI 方式运行,双击启动后不会弹出黑框,体验更接近原生桌面应用。
- 开发者侧:debug 模式下仍能看到控制台输出,方便打印日志和排查问题;release 模式下自动隐藏控制台,交付给用户时界面干净整洁。
这正是windows-subsystem与cfg_attr组合使用的核心价值所在。