11
0

WinUI Rust 学习笔记-01 环境搭建

2026-08-17
2026-08-17
文章摘要
|

微软官方的windows-rs库最近已经支持了winui3,可以直接使用winui3的控件了。链接地址:windows-rs/docs/crates/windows-reactor.md at master · microsoft/windows-rs

1. 整体需要什么

开发 Windows Reactor 应用,本质上是在 Rust 里调用 WinUI 3(微软的 Windows 原生 UI 框架)。 因此环境由三部分组成:

组件

作用

安装方式

Rust 工具链

编译 Rust 代码

rustup

MSVC 构建工具

提供 C/C++ 链接器与 Windows SDK

Visual Studio Build Tools

Windows App SDK 运行时

WinUI 3 控件的运行时支持

由构建脚本自动获取

不需要安装 Visual Studio 全家桶、不需要 C#、不需要 XAML 工具链。 我们只用 Rust 写代码,Windows App SDK 的运行时文件由 windows-reactor-setup 这个构建辅助 crate 自动下载部署。

2. 安装 Rust 工具链

如果你已经通过 rustup 安装了 Rust 并默认使用 MSVC 目标,本步可跳过(用下面的验证命令确认即可)。

2.1 安装 rustup

访问 https://rustup.rs,或直接在 PowerShell 中运行:

winget install Rustlang.Rustup

2.2 确认 MSVC 目标

Windows Reactor 要求 x86_64-pc-windows-msvc 目标(需要 MSVC 链接器,见第 3 节):

rustup target list --installed

输出中应包含 x86_64-pc-windows-msvc。如果没有,运行:

rustup default stable-x86_64-pc-windows-msvc

3. 安装 Visual Studio Build Tools

Rust 的 MSVC 目标在链接阶段需要微软的 link.exe,它来自 Visual Studio 的 C++ 工具集。

3.1 安装(二选一)

  • 方式 A(推荐):仅安装轻量的 Build Tools:

    winget install Microsoft.VisualStudio.2022.BuildTools --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.Windows11SDK.22621"
  • 方式 B:安装完整 Visual Studio 2022,勾选「使用 C++ 的桌面开发」工作负载。

说明:VCTools 工作负载包含 MSVC 编译器与链接器;Windows11SDK.22621 是 Windows SDK。 如果你用方式 B 且已有 VS2022,只需在 Visual Studio Installer 中确认勾选「使用 C++ 的桌面开发」。

3.2 验证

安装完成后,重新打开 PowerShell(让环境变量生效),确认能找到链接器:

where.exe link

如果找不到,但确实装好了 Build Tools,可以手动运行:

# 以管理员身份执行,或将该路径写入用户环境变量 PATH
"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\Tools\VsDevCmd.bat"

更简单的验证方式:直接编译一个带链接的项目(第 4 节的 cargo check 就够)。

4. 验证环境

在 PowerShell 中依次运行:

rustc --version    # 例如 rustc 1.97.1 (8bab26f4f 2026-07-14)
cargo --version    # 例如 cargo 1.97.1 (c980f4866 2026-06-30)

要求 Rust 1.95 或更高windows-reactor 的最低支持版本,且使用 edition 2024)。

5. 获取 windows-rs 源码

项目工程依赖 windows-reactor 的最新开发版,而它目前只能作为 windows-rs 仓库的 workspace 成员使用(原因见下文「发布状态」),所以先克隆仓库:

git clone https://github.com/microsoft/windows-rs.git
cd windows-rs

如果你克隆的是更新后版本,会看到以下关键目录:

windows-rs/
├── Cargo.toml                      # workspace 根清单
├── crates/
│   ├── libs/
│   │   ├── reactor/                # ★ windows-reactor 源码(本教程的主角)
│   │   ├── reactor-setup/          # 构建辅助:部署 Windows App SDK 运行时
│   │   ├── core/                   # windows-core 基础类型(HRESULT、Result 等)
│   │   └── ...                     # 其余 30+ 个基础 crate
│   ├── samples/
│   │   ├── reactor/                # ★ 官方示例(120+ 个,含 gallery 应用)
│   │   └── ...
│   └── tools/
├── docs/
│   └── crates/
│       └── windows-reactor.md      # ★ 官方英文文档

6. 关于 Windows App SDK 运行时

WinUI 3 控件运行时不随系统分发,需要从 NuGet 获取。windows-reactor-setupbuild.rs 中自动处理。

Windows App SDK 运行时下载链接:最新Windows 应用 SDK下载 - Windows apps | Microsoft Learn

有两种部署模型,对应 build.rs 中调用不同函数:

部署模型

build.rs 函数

运行时

何时用

框架依赖

as_framework_dependent()

本机必须已安装 Windows App SDK Runtime,或由构建脚本下载 bootstrap DLL 自动引导

日常开发、调试(示例项目采用)

自包含

as_self_contained()

构建时把整个运行时打进输出目录,目标机器无需预装

分发给其他电脑

框架依赖模式在首次运行时,bootstrap() 会加载随程序输出的 microsoft.windowsappruntime.bootstrap.dll,自动初始化匹配的 Windows App SDK 运行时。 若本机未安装运行时,构建脚本会尝试联网下载所需包(需要网络)。

7. 第一个示例项目(快速验证环境)

7.1. 项目全景

一个 Windows Reactor 应用由三个文件组成:

winui-study/
├── Cargo.toml      # 项目清单:声明依赖
├── build.rs        # 构建脚本:部署 Windows App SDK 运行时
└── src/
    └── main.rs     # 应用代码:render 函数 + main

7.2. Cargo.toml:声明依赖

[package]
name = "winui-study"
version = "0.1.0"
edition = "2024"   # windows-reactor 要求 edition 2024

[dependencies]
windows-reactor = {path = "./windows-rs/crates/libs/reactor"}   # ★ 唯一的运行时依赖

[build-dependencies]
windows-reactor-setup = {path = "./windows-rs/crates/libs/reactor-setup"}  # ★ 构建期依赖

几个要点(crates.io 上仅有 0.0.0 占位版本,所以下载后本地引入):

  • windows-reactor运行时依赖,提供 UI 库的全部类型(RenderCxElementtext_blockbuttonApp……)。

  • windows-reactor-setup构建期依赖,只被 build.rs 使用,负责部署运行时。

3. build.rs:部署运行时

fn main() {
    // 框架依赖模式:构建时把 bootstrap 引导库复制到输出目录
    windows_reactor_setup::as_framework_dependent();
}

build.rs 是 Cargo 的构建钩子,在编译 main.rs 之前执行。 as_framework_dependent() 会把 microsoft.windowsappruntime.bootstrap.dll (按目标架构选 x64/x86/arm64)复制到构建输出目录,供程序启动时引导 Windows App SDK 运行时。

如果你想打包一个「拷给别人就能跑」的程序,把这一行换成:

windows_reactor_setup::as_self_contained();   // 自包含模式

此时构建脚本会下载完整的 Windows App SDK Runtime 打进输出目录,目标机器无需预装运行时。 代价是构建更慢、产物更大。两种模式二选一即可。

4. main.rs:应用代码

先看完整的 main.rs(最小示例):

#![windows_subsystem = "windows"]  //1. 不弹出控制台窗口

use windows_reactor::*;   //2.导入库中全部公共API

fn app(_cx: &mut RenderCx) -> Element {   // 3.render 函数,把状态映射为界面
    vstack((                           //  4.垂直布局容器
        text_block("你好,Windows Reactor!")    //文本控件
            .font_size(28.0)               //字号 28
            .bold(),                       //加粗                                   
        text_block("这是一段由 Rust 渲染的 WinUI 3 文本"),
    ))
    .spacing(8.0)       // 5.子元素间距 8 逻辑像素
    .into()             //6.把 builder 转成 Element
}

fn main() -> Result<()>{   // 7.程序入口
    bootstrap()?;    //  8.初始化Windows APP SDK 运行时
    App::new()       // 9.创建应用
        .title("Hello, World!")   //窗口标题 
        .render(app)          // 10.传入 render 函数并启动消息循环
}

逐行解释:

(1) #![windows_subsystem = "windows"]

告诉链接器:这是 GUI 程序,不分配控制台。这样运行时不会多出一个黑框。 (放在文件最顶部。)

(2) use windows_reactor::*;

导入库的所有公共 API。示例代码都会写这一行,之后所有控件名、AppRenderCx 等都直接可用。windows_reactor 还重导出了 windows_coreResultError 等基础类型。

(3) render 函数

fn app(cx: &mut RenderCx) -> Element

这是 Reactor 应用的核心约定:一个「把当前状态渲染成界面」的纯函数

  • 参数 cx: &mut RenderCx:渲染上下文,用来读取/更新状态(hooks)。

  • 返回值 Element:描述界面的元素树。

  • Reactor 每次状态变化都会重新调用这个函数,算出新界面,再与旧界面做差异比较 (diff),只更新发生变化的部分。你不需要手动增删控件。

对比:传统 WinUI/C# 方式是你自己写「先创建控件 → 放进容器 → 注册事件 → 手动更新」。 Reactor 方式是你只声明「界面长什么样」,剩下的交给框架。

(4) 布局与控件

vstack(( ... ))        // 垂直堆叠容器(VerticalStackPanel 的封装)
text_block("...")      // 文本控件(TextBlock 的封装)
button("...")          // 按钮控件(Button 的封装)

Reactor 里每个控件都对应一个构造器函数(builder)。 vstack/hstack 接受一个元组作为子元素列表。

(5) .spacing(8.0)

链式方法设置属性。vstack(...) 返回一个 StackPanel builder, .spacing() 设置子元素间距,单位是 DIP(设备无关像素,1 DIP ≈ 1/96 英寸)。

(6) .into()

每个 builder 最后都必须 .into() 转成 Element。这是 Reactor 的设计: builder(可配置的构造器)→ Element(不可变的、描述界面的值)。 忘了写 .into() 会得到类型不匹配的编译错误,这是最常遇到的报错之一。

(7)(8) mainbootstrap

fn main() -> Result<()> {   // Result 来自 windows_reactor 的重导出
    bootstrap()?;           // 初始化 Windows App SDK 运行时
    ...
}
  • bootstrap() 必须在创建任何 WinUI 控件之前调用一次(仅框架依赖模式需要)。 它找到本机安装的 Windows App SDK 运行时并初始化。

  • main 返回 Result<()>:如果初始化失败,错误会沿 ? 传播到进程退出,并打印错误信息。

(9)(10) Apprender

App::new()            // 应用构建器
    .title("Hello Reactor")   // 窗口标题
    .render(app)      // 传入 render 函数,启动 WinUI 消息循环,阻塞直到所有窗口关闭

App 是一个构建器,常用选项(均为可选):

方法

作用

示例

.title(..)

窗口标题

.title("我的应用")

.inner_size(w, h)

窗口初始大小

.inner_size(800.0, 600.0)

.fullscreen(true)

全屏

.fullscreen(true)

.backdrop(..)

窗口背景效果

.backdrop(Backdrop::Mica)

.icon(path)

窗口图标(.ico 文件路径)

.icon("assets/app.ico")

.on_exit(..)

最后一个窗口关闭后、进程退出前回调

.on_exit(|| save_data())

如果一切正常,会弹出一个窗口,显示「你好,Windows Reactor!」。 第一次构建需要编译整个依赖树(几分钟),之后会很快。

运行效果图:

打不开窗口?见下方「常见问题」。

8. 常见问题

8.1 link.exe not found / 链接器错误

MSVC 构建工具未安装或环境未生效。回到第 3 节安装 Build Tools,并重新打开终端

8.2 首次构建下载失败 / 超时

框架依赖模式需要网络下载 Microsoft.WindowsAppRuntime.Bootstrap.dll 相关资源,建议提前安装好Windows App SDK 运行时。 确认网络通畅后重试;如果被墙,可配置代理:

$env:HTTP_PROXY = "http://127.0.0.1:7890"
$env:HTTPS_PROXY = "http://127.0.0.1:7890"

8.3 运行时报 0x80073CF3 或「找不到 Windows App Runtime」

本机未安装 Windows App SDK Runtime。可以从 Microsoft Store 安装 「Windows App SDK Runtime」,或让构建脚本以自包含方式打包(见第 6 节)。

9. 关于发布状态(重要)

windows-reactor 目前仍处于开发阶段(0.100 开发版,尚未发布crate.io中):

  • crates.io 上仅有 0.0.0 占位版本,尚无稳定发布;

  • 因此笔记示例项目采用「本地源码引入」方式运行;

  • 待官方正式发布后,就可以在自己的项目中 cargo add windows-reactor 即可,API 不变。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

评论