使用 Winapp CLI 搭配 Tauri

本指南示範如何在 Tauri 應用程式中使用 winapp CLI 除錯套件識別碼,並將應用程式打包為 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 名稱tauri-app(或您偏好的名字)
  • 前端語言JavaScript
  • 套件管理器npm
  • 使用者介面範本Vanilla
  • 介面風格JavaScript

前往你的專案目錄並安裝相依套件:

cd tauri-app
npm install

執行應用程式確認一切正常:

npm run tauri dev

2. 更新代碼以驗證身份

我們會更新應用程式,以檢查它是否運行於具有套件識別的狀態。 我們會使用 Rust 後端的 windows crate 來存取 Windows APIs,並將其暴露給前端。

後端變更(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 指令:在同一檔案中 (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)
  • Publisher name:按 Enter 接受預設或輸入你的名字
  • 版本:按下 "Enter" 以接受 1.0.0.0
  • 入口點:按 Enter 接受預設(tauri-app.exe)
  • 設定 SDK:選擇「不要設定 SDK」(Tauri 使用 Rust windows 的 crate,不是 C++ SDK 標頭)

這個命令將會執行以下作業:

  • Create Package.appxmanifest — 定義你應用程式身份的清單
  • 建立 Assets 資料夾 — MSIX 包裝與商店提交所需的圖示

Note

因為沒有管理 SDK 套件,所以沒有 winapp.yaml 被建立,Tauri 是透過 Cargo 使用 Rust 的 windows crate,因此 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 文件放入 dist 資料夾(而 target\debug 資料夾很大,包含不屬於你應用程式的中間編譯產物)。
    • winapp run .\\dist: 註冊一個鬆散的版面套件(就像真實的 MSIX 安裝一樣),然後啟動應用程式。
  2. 執行劇本

    npm run tauri:dev:withidentity
    

Tip

你可能會看到應用程式視窗後方會出現終端機/主控台視窗——這是 Tauri 除錯編譯的正常現象(它是 Rust 程序的主控台)。

你現在應該會看到應用程式開啟,並顯示出「套件家族名稱」,以確認其正在運行並具有身份! 你現在可以開始使用和除錯需要套件身份的 API,例如 Notifications 或像 Phi Silica 這類新的 AI API。

Tip

winapp run 同時也會在你的系統上註冊包裹。 這也是為什麼當你在第 5 步嘗試安裝時,MSIX 可能會顯示為「已安裝」。 完成後,請使用 winapp unregister 清理開發套件。

Tip

關於進階除錯工作流程(附加除錯器、IDE 設定、啟動除錯),請參閱 除錯指南

5. 使用 MSIX 打包

當你準備好發佈應用程式時,可以把它打包成 MSIX,這樣就能為你的應用程式提供套件身份。

首先,將一段pack:msix script 添加到您的package.json中。

"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 文件放入 dist 資料夾(而 target\release 資料夾很大,包含不屬於你應用程式的中間編譯產物)。
  • winapp pack .\\dist --cert .\\devcert.pfx:將應用程式包裝並以 MSIX 簽名。

產生開發證書

MSIX 套件必須簽署。 本地測試時,產生自簽開發憑證:

winapp cert generate --if-exists skip

Tip

證書的發行者必須與您 Publisher 中的 Package.appxmanifest 相符。 cert generate指令會自動從你的清單讀取這些資訊。

組裝、分期與打包

npm run pack:msix

Tip

pack 指令會自動從你目前的目錄中使用 Package.appxmanifest,並在打包前將其複製到目標資料夾。 產生的 .msix 檔案會放在目前的目錄中。

安裝憑證

在安裝 MSIX 套件之前,你需要先信任你機器上的開發憑證。 以管理員身份執行這個指令(你只需要在每個憑證上執行一次):

winapp cert install .\devcert.pfx

安裝並執行

Tip

如果你在第四步使用 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 需要更高的版本號才能更新已安裝的套件。

安裝完成後,你可以從開始選單啟動應用程式。 你應該會看到應用程式正在以識別執行。

Tips

  1. 一旦準備好分發,你可以用憑證授權中心的程式碼簽署憑證來簽署 MSIX,讓使用者不必安裝自簽憑證。
  2. Microsoft Store 會幫你簽署 MSIX,提交前不需要簽名。
  3. 你可能需要建立多個 MSIX 套件,分別針對你支援的架構(x64、Arm64)。

後續步驟