将 winapp CLI 与 Tauri 配合使用

本指南演示如何将 winapp CLI 与 Tauri 应用程序配合使用,以包标识进行调试,并将应用程序打包为 MSIX。

包标识是Windows app模型中的核心概念。 它允许应用程序访问特定的Windows API(例如通知、安全、AI API 等),具有干净的安装/卸载体验等。

有关完整的工作示例,请查看此存储库中的 Tauri 示例

先决条件

  1. Windows 11
  2. Node.js - winget install OpenJS.NodeJS --source winget
  3. Rust 工具链 - 使用 rustup 安装 Rust 或 winget install Rustlang.Rustup --source winget
  4. winapp CLI - winget install microsoft.winappcli --source winget

Tip

如果已安装这些更新,请无论如何运行 winget install 命令来检查更新。

1.创建新的 Tauri 应用

首先,使用官方基架工具创建新的 Tauri 应用程序:

npm create tauri-app@latest

按照提示操作:

  • Project nametauri-app(或首选名称)
  • 前端语言JavaScript
  • 包管理器npm
  • UI 模板Vanilla
  • UI 风格JavaScript

导航到project目录并安装依赖项:

cd tauri-app
npm install

运行应用以确保一切正常工作:

npm run tauri dev

2. 更新代码以检查标识

我们将更新应用,以检查它是否使用包标识运行。 我们将使用 Rust 后端中的 windows 箱访问 Windows API 并将其公开到前端。

后端更改 (Rust)

  1. 添加依赖项:打开 src-tauri/Cargo.toml 并在文件末尾添加以下行。 这会添加Windows API 绑定,以便我们可以检查包标识:

    [target.'cfg(windows)'.dependencies]
    windows = { version = "0.58", features = ["ApplicationModel"] }
    
  2. 添加命令:打开 src-tauri/src/lib.rs 并添加 get_package_family_name 函数。 将其置于 pub fn run() 函数之前。

    #[tauri::command]
    fn get_package_family_name() -> String {
        #[cfg(target_os = "windows")]
        {
            use windows::ApplicationModel::Package;
            match Package::Current() {
                Ok(package) => {
                    match package.Id() {
                        Ok(id) => match id.FamilyName() {
                            Ok(name) => name.to_string(),
                            Err(_) => "Error retrieving Family Name".to_string(),
                        },
                        Err(_) => "Error retrieving Package ID".to_string(),
                    }
                }
                Err(_) => "No package identity".to_string(),
            }
        }
        #[cfg(not(target_os = "windows"))]
        {
            "Not running on Windows".to_string()
        }
    }
    
  3. Register Command:在同一文件中(src-tauri/src/lib.rs)更新 run 函数以注册新命令:

    pub fn run() {
        tauri::Builder::default()
            .plugin(tauri_plugin_opener::init())
            .invoke_handler(tauri::generate_handler![greet, get_package_family_name]) // Add get_package_family_name here
            .run(tauri::generate_context!())
            .expect("error while running tauri application");
    }
    

前端更改 (JavaScript)

  1. 更新 HTML:打开 src/index.html 并添加段落以显示结果:

    <!-- ... inside <main> ... -->
    <p id="pfn-msg"></p>
    
  2. 更新逻辑:打开 src/main.js 以调用命令并显示结果:

    const { invoke } = window.__TAURI__.core;
    
    // ... existing code ...
    
    async function checkPackageIdentity() {
      const pfn = await invoke("get_package_family_name");
      const pfnMsgEl = document.querySelector("#pfn-msg");
    
      if (pfn !== "No package identity" && !pfn.startsWith("Error")) {
        pfnMsgEl.textContent = `Package family name: ${pfn}`;
      } else {
        pfnMsgEl.textContent = `Not running with package identity`;
      }
    }
    
    window.addEventListener("DOMContentLoaded", () => {
      // ... existing code ...
      checkPackageIdentity();
    });
    
  3. 现在,像往常一样运行应用:

    npm run tauri dev
    

    应用窗口中应会显示“未使用包标识运行”。 这确认标准开发版本在没有包标识的情况下正在运行。

3.使用 winapp CLI 初始化Project

winapp init 命令一次性设置所需的一切:应用清单和资产。 清单定义应用的标识(名称、发布者、版本),Windows用于授予 API 访问权限。

运行以下命令并按照提示操作:

winapp init

出现提示时:

  • 包名称:按 Enter 接受默认值(tauri-app)
  • 发布者名称:按 Enter 接受默认值或输入名称
  • 版本:按 Enter 接受 1.0.0.0
  • 入口点:按 Enter 接受默认值(tauri-app.exe)
  • 设置 SDK:选择“不设置 SDK”(Tauri 使用 Rust 的 windows 箱子,而不是 C++ SDK 标头)

此命令将:

  • 创建 Package.appxmanifest — 定义您应用身份的清单
  • 创建 Assets 文件夹 - MSIX 打包和应用商店提交所需的图标

注释

由于没有管理 SDK 包,因此不会创建任何winapp.yaml —— 因为 Tauri 通过 Cargo 使用 Rust 的windows库,所以没有什么可以给winapp restore/update监控。

可以打开 Package.appxmanifest 以进一步自定义属性,如显示名称、发布者和功能。

4.使用标识进行调试

若要使用标识进行调试,我们需要构建 Rust 后端并使用这个运行 winapp run。 由于 npm run tauri dev 管理进程生命周期,因此很难在那里注入标识。 相反,我们将创建自定义脚本。 调试不需要证书或签名。

  1. 添加脚本:打开 package.json 并添加新脚本 tauri:dev:withidentity

    "scripts": {
      "tauri": "tauri",
      "tauri:dev:withidentity": "cargo build --manifest-path src-tauri/Cargo.toml && (if not exist dist mkdir dist) && copy /Y src-tauri\\target\\debug\\tauri-app.exe dist\\ >nul && winapp run .\\dist"
    }
    

    此脚本的作用:

    • cargo build ...:重新编译 Rust 后端。
    • copy ... dist\\:将 exe 暂存到文件夹中 disttarget\debug 该文件夹非常大,并且包含不属于应用的中间生成项目)。
    • winapp run .\\dist:注册松散布局包(就像真正的 MSIX 安装一样),并启动应用。
  2. 运行脚本

    npm run tauri:dev:withidentity
    

Tip

你可能会看到终端/控制台窗口显示在应用窗口后面 - 这是 Tauri 调试生成的正常情况(它是 Rust 进程的控制台)。

现在应会看到应用打开并显示“程序包系列名称”,确认它正在运行并具有标识! 现在可以开始使用和调试需要包标识的 API,例如通知或新的 AI API(如 Phi 硅)。

Tip

winapp run 还会在您的系统中注册该软件包。 这就是为什么在步骤 5 的后面尝试安装 MSIX 时,MSIX 可能显示为“已安装”。 使用 winapp unregister 清理开发包以完成工作。

Tip

有关高级调试工作流(附加调试器、IDE 设置、启动调试),请参阅 调试指南

5. 将包与 MSIX 配合使用

准备好分发应用后,可以将其打包为 MSIX,它将为应用程序提供包标识。

首先,向您的package.json添加pack:msix脚本。

"scripts": {
  "tauri": "tauri",
  "tauri:dev:withidentity": "...",
  "pack:msix": "npm run tauri -- build && (if not exist dist mkdir dist) && copy /Y src-tauri\\target\\release\\tauri-app.exe dist\\ >nul && winapp pack .\\dist --cert .\\devcert.pfx"
}

此脚本的作用:

  • npm run tauri -- build:在发布模式下生成 Rust 后端。
  • copy ... dist\\:将 exe 暂存到文件夹中 disttarget\release 该文件夹非常大,并且包含不属于应用的中间生成项目)。
  • winapp pack .\\dist --cert .\\devcert.pfx:将应用打包并签名为 MSIX。

生成开发证书

必须对 MSIX 包进行签名。 对于本地测试,请生成自签名开发证书:

winapp cert generate --if-exists skip

Tip

证书的发布者必须与 Package.appxmanifest 中的 Publisher相匹配。 该 cert generate 命令会自动从清单中读取此内容。

构建、准备和封装

npm run pack:msix

Tip

pack 命令会自动使用当前目录中的 Package.appxmanifest,并在打包之前将其复制到目标文件夹。 生成的 .msix 文件将位于当前目录中。

安装证书

在安装 MSIX 包之前,需要信任计算机上的开发证书。 以管理员身份运行此命令(每个证书只需执行此操作一次):

winapp cert install .\devcert.pfx

安装和运行

Tip

如果在步骤 4 中使用 winapp run ,则可能已在系统上注册包。 首先使用 winapp unregister 删除开发注册,然后安装发布包。

双击生成的 .msix 文件或使用 PowerShell 安装包:

Add-AppxPackage .\tauri-app.msix

Tip

MSIX 文件名包括版本和体系结构(例如)。 tauri-app_1.0.0.0_x64.msix 检查目录的确切文件名。 如果需要在代码更改后重新打包,请在 Version 中递增 Package.appxmanifest — Windows需要更高的版本号来更新已安装的包。

安装后,可以从“开始”菜单启动应用。 您应该看到该应用正在使用身份运行。

提示

  1. 准备好分发后,可以使用证书颁发机构的代码签名证书对 MSIX 进行签名,以便用户无需安装自签名证书。
  2. Microsoft Store将为你签名 MSIX,无需在提交之前进行签名。
  3. 您可能需要为每个支持的体系结构(x64, Arm64)分别创建一个 MSIX 包。

后续步骤

  • 通过 winget 分发:将 MSIX 提交到 Windows 程序包管理器 社区存储库
  • 发布到 Microsoft Store:使用 winapp store 提交包
  • 设置 CI/CD:使用 GitHub Action 在流水线中自动打包
  • 探索 Windows APIs:使用包标识,现在可以使用通知设备端 AI和其他身份依赖的 API