CLI 文件與使用

殼體完備

啟用指令、選項和數值的分頁補全功能。 請參閱 Shell Completion 指南 以獲得設定說明。

# Quick setup for PowerShell (permanent — add to profile)
winapp complete --setup powershell >> $PROFILE

# Or try it in the current session only
winapp complete --setup powershell | Out-String | Invoke-Expression

初始化

用 Windows SDK、Windows 應用程式 SDK,和現代 Windows 開發所需的資產來初始化目錄。

winapp init [base-directory] [options]

引數:

  • base-directory - 應用程式/工作區的基礎/根目錄(預設:目前目錄)

選項:

  • --config-dir <path> - 用於讀取/儲存設定的目錄(預設:選取的專案目錄,或若未偵測到專案則為目前目錄)
  • --setup-sdks - SDK 安裝模式:「穩定」(預設)、 「預覽」、「實驗性」或「無」(跳過 SDK 安裝)
  • --ignore-config, --no-config - 不要使用設定檔來管理版本
  • --no-gitignore - 不要更新 .gitignore 檔案
  • --use-defaults, --no-prompt - 不要提示,並預設所有提示
  • --config-only - 僅處理設定檔操作,跳過套件安裝
  • --exe <path> - 應用程式執行檔的路徑。 需要 --sparse。 它會為 exe 產生一個只包含身份的稀疏清單,而不是完整的套件或 SDK 設定。
  • --sparse - 為現有桌面執行檔產生稀疏身份清單(appxmanifest.xml)。 跳過 SDK 或套件安裝。 與 --exe 搭配使用。
  • --name <name> - 覆寫套件名稱(僅限稀疏;預設:由執行檔推斷)
  • --publisher <CN> - 覆寫發佈商 CN(僅限稀疏;預設:由執行檔公司名稱推斷)
  • --output-dir <path> - 用來寫入 sparse manifest 和 Assets/ 的目錄(僅 sparse;預設為 sparse/ 當前目錄中的資料夾)
  • --force - 覆蓋目標目錄中存在 appxmanifest.xml 的(僅稀疏)。 沒有它,init 會失敗,而不是替換現有的清單或資產。
  • --add-js-bindings (僅限 npm) - 新增 winapp.jsBindings 至 package.json 並產生 JS/TypeScript 綁定,無需提示(與 --setup-sdks none)

它的用途:

  • 建立 winapp.yaml 設定檔(僅在管理 SDK 套件時;跳過時則有 --setup-sdks none)
  • 下載 Windows SDK 及 Windows 應用程式 SDK 套件
  • 產生 C++/WinRT 標頭與二進位檔
  • 建立 Package.appxmanifest
  • 建立建置工具並啟用開發者模式
  • 更新 .gitignore 以排除產生的檔案
  • 將可分享檔案儲存在全域快取目錄中
  • 啟用 Windows 應用程式 SDK API 時(僅限 npm)產生 JS 綁定

自動專案偵測:

當 init 執行時沒有目錄參數,會對目前目錄樹進行廣度優先搜尋,以尋找相容的專案(最多 10 個)。 支援的專案類型:

  • Tauri — tauri.conf.json 在目錄下一層發現
  • 電子 — package.json 具有 electron in 依賴關係或 devDependencies
  • Flutter — pubspec.yaml 專案的根源
  • .NET — .csproj 在專案根節點
  • Rust — Cargo.toml 專案根源
  • C++ — CMakeLists.txt 在專案根節點

搜尋會跳過常被忽略的目錄(node_modules、bin、obj、.git 等)。 當找到相容專案時,不會搜尋其下方的子目錄。

  • 若提供目錄參數(例如 ,或winapp init .),winapp init path/to/project則跳過搜尋,僅init檢查該目錄是否相容專案
  • 若 --use-defaults (或 --no-prompt) 未設定目錄參數,則 init 跳過搜尋並非互動式初始化目前目錄,若未偵測到已知專案類型(例如 ) winapp init --use-defaults則先警告
  • 在非互動環境(管道標準、CI、重定向輸入)中,會 init 自動使用 --use-defaults 行為並發出警告: Non-interactive environment detected. Using default values.
  • 如果目前的目錄是相容的專案, init 則會立即進行
  • 如果在其他地方找到一個專案,系統會提示你確認
  • 如果發現多個專案,你可以選擇要初始化哪一個——目前的目錄永遠是備用選項
  • 如果找不到專案,會被警告並詢問是否繼續進行
  • 若搜尋達到 10 個專案的限制,則會提示提供目錄參數

自動 .NET 專案流程:

當目標目錄中發現 .csproj 檔案時,init 會使用簡化的 .NET 特定流程:

  • 驗證並更新 TargetFramework 為相容Windows的 TFM(例如 net10.0-windows10.0.26100.0)
  • 將Microsoft.WindowsAppSDK和Microsoft.Windows.SDK.BuildTools直接添加為PackageReference中的NuGet.csproj條目
  • 產生Package.appxmanifest、資產和開發證書
  • 不會建立winapp.yaml或下載 C++ 投影(用於 dotnet restore NuGet 套件)

稀疏恆等模式(--exe + --sparse):

為現有桌面執行檔產生僅識別身份的稀 疏套件 清單——稀 疏套件工作流程的第一步。 與完整 init 流程不同,這 會跳過所有 SDK/套件安裝 (稀疏身份套件沒有 SDK 依賴),只產生清單和佔位資產。

  • 透過(用 --name、 --publisher、 或互動式方式)從執行檔FileVersionInfo推斷套件名稱、發佈者、描述和版本
  • appxmanifest.xml 將(將 exe 名稱替換成 Executable)加上一個Assets/資料夾寫入目前目錄中的某sparse/個資料夾(或 --output-dir)
  • 用於 --use-defaults/--no-prompt 跳過互動覆寫提示(CI 友善)
  • --exe 沒有 --sparse 則為錯誤

資產是外部的。 稀疏 .msix 僅為身份:產生 Assets/ 的檔案是在執行時從應用程式的安裝目錄(外部內容位置)解析, 而非 捆綁在 .msix. 將它們與你的應用程式一起部署。

接下來 winapp init --exe <exe> --sparse的步驟: winapp pack <appxmanifest.xml> 建立恆等式 .msix,然後 winapp embed-identity <exe>。 完整攻略請參閱 稀疏包裝指南 。

範例:

# Initialize current directory
winapp init

# Initialize with experimental packages
winapp init --setup-sdks experimental

# Initialize specific directory without prompts
winapp init ./my-project --use-defaults

# Initialize a .NET project (auto-detected from .csproj)
cd my-dotnet-app
winapp init

# Generate a sparse identity manifest for an existing exe (no SDK install)
winapp init --exe ./bin/Release/net8.0-windows/MyApp.exe --sparse --use-defaults

提示:初始設定後安裝 SDK

如果你已經使用 init--setup-sdks none (或跳過 SDK 安裝)但之後需要 SDK:

# Re-run init to install SDKs - preserves existing files (manifest, etc.)
winapp init . --use-defaults --setup-sdks stable

使用 --setup-sdks preview 或 --setup-sdks experimental 用於預覽/實驗性的 SDK 版本。


新增

從官方 Windows 應用程式 SDK dotnet new 範本建立一個新的 WinUI 應用程式。 預設為互動式;在非互動環境中自動使用預設值。

winapp new [options]

選項:

  • -t, --template <short-name> - 模板簡稱(例如 winui, winui-navview, winui-mvvm, winui-lib, winui-unittest, , 或實驗反應爐模板如 reactor 或 reactor-mvu)。 執行時與已安裝的套件進行驗證;快去 winapp new --list 看看一切。 預設值: winui (空白 XAML 應用程式)。
  • -n, --name <name> - 新應用程式/專案名稱(預設:源自 --output、 否則 WinUIApp)
  • -o, --output <path> - 建立應用程式的目錄(預設: ./<name>)
  • --use-defaults, --no-prompt - 不提示;使用預設值(空白模板、名稱來源 --output/--name,並保留已安裝的模板包而非更新)
  • --force - 即使輸出目錄已包含檔案,仍可維持支架
  • --template-version <latest|installed|version> - WinUI 模板包版本: latest 安裝最新發佈的套件, installed 保留已下載的內容(無網路),或釘選明確版本 1.2.3如 。 預設值:當沒有包時安裝最新的,否則會提示更新過時的包(as-is --use-defaults在 下)。
  • --list - 列出可用的 WinUI 範本並退出(若未安裝,請先安裝最新套件)
  • --json - 輸出格式化為 JSON

範本:

這個套件附帶兩種 WinUI 應用程式。 XAML 範本會以 C# 代碼背後的標記定義使用者介面。 反應器 範本是純 C#,沒有 XAML,採用 MVU(Model-View-Update)模式。 範本清單是從已安裝的套件即時讀取,因此它總是反映你擁有的版本——執行 winapp new --list 以查看目前的套裝。 常見範本:

簡短名稱 說明
winui 最小空白 XAML 應用程式(MSIX 封裝)
winui-navview XAML NavigationView 入門應用程式
winui-tabview XAML TabView 入門應用程式
winui-mvvm XAML MVVM 應用程式 (CommunityToolkit.Mvvm)
winui-lib WinUI 3 類別函式庫
winui-unittest 打包式 MSTest 應用程式;啟動時會執行測試
reactor 實驗性。 Blank Reactor 應用程式 — 純 C#,沒有 XAML
reactor-mvu 實驗性。 反應器應用程式示範MVU模式
reactor-navview 實驗性。 反應爐導航檢視入門應用程式
reactor-tabview 實驗性。 Reactor TabView 入門應用程式

反應爐模板是實驗性質。 它們參考預發布 Microsoft.UI.Reactor 套件,這些套件的 API 可能會在未來版本中變更或移除。 winapp new在互動式選擇器中標記(實驗性),--list設置"Experimental": true於 --json,並在搭建支架後列印警告。 它們從來不會被選為預設範本。 Reactor 也需要 .NET 10 SDK 或更新版本;舊版 SDK winapp new 會先用它需要的版本失敗,而不是搭建無法建構的專案。

每個範本的標準短名稱即為其首批別名 dotnet new 列表;任何列出的別名(例如 winui3、 wasdk-single、 winui-reactor) 也皆可接受。 在現有的 WinUI 專案中執行時, dotnet new 也會顯示 項目 範本(例如空白頁面),這 winapp new 會新增到目前專案中,而不是建立新的專案。

範本包版本管理:

winapp new 不再釘選特定範本包版本。 如果沒有安裝擴充包,它會安裝最新的。 如果舊的包已經安裝,它會檢查串流,當有新的包存在時, 會提示 是否更新——但非互動--use-defaults 式/執行時會保留已安裝的包。 以前 --template-version latest 總是不打招呼就直接拿最新款,或 --template-version installed 是直接用下載的包,不用檢查網路。 傳遞 明確 版本(例如 --template-version 1.2.3)總是安裝該版本——即使已有新套件,仍需重新安裝——因此支架結構可跨機器重現。

首次運行可能會花費較長時間:安裝或更新範本包,或還原所選範本所使用的缺少的 Windows 應用程式 SDK NuGet 套件,可能需要額外下載。 這種情況也可能發生在新版 Windows 應用程式 SDK 發布後。 如果支架在 10 秒後仍在運行,則 winapp new 更新狀態訊息,表示套件可能正在下載或還原。

它的用途:

  • 驗證 .NET SDK 已安裝(若缺少指引,快速失敗——winapp不安裝工具鏈)
  • 按需安裝或更新官方 WinUI 模板包 (Microsoft.WindowsAppSDK.WinUI.CSharp.Templates)
  • 列舉已安裝套件中的可用範本,並將支架委派給 dotnet new <short-name>

WinUI 應用程式範本已經包含 Windows 封裝和身份碼(),Package.appxmanifest因此不需要額外winapp init步驟。 對於應用程式範本,請用來 winapp run 建立並啟動應用程式。 範本 winui-lib 會產生一個類別函式庫,供參考應用程式專案(該函式庫沒有應用程式清單)。 該 winui-unittest 範本是一個 打包好的 MSTest 應用程式,其測試會在應用程式啟動時執行 (winapp run),而非透過 dotnet test。 winapp new在你已安裝的 .NET SDK 目標框架上搭建支架,並列印出你所選範本的適當下一步。

傳遞全域 --verbose (-v)旗標以回應每個底層 dotnet 調用(包查詢、更新檢查、安裝、 dotnet new list支架)及其完整輸出——這對於診斷模板包或支架問題非常有用。

範例:

# Interactive: pick a template, then a name (output defaults to ./<name>)
winapp new

# List the available templates without scaffolding
winapp new --list

# One-shot with a specific template
winapp new --name MyApp --template winui-navview

# Experimental Reactor app (pure C#, no XAML) — requires the .NET 10 SDK
winapp new --name MyApp --template reactor-mvu

# Always use the newest template pack, no prompts
winapp new --name MyApp --template-version latest --use-defaults

# Show the underlying dotnet commands and their output
winapp new --name MyApp --verbose

# Non-interactive (agent) with machine-readable output
winapp new --use-defaults --name MyApp --json

回復

還原套件並根據現有 winapp.yaml 設定重新產生檔案。

winapp restore [base-directory] [options]

引數:

  • base-directory - 還原目錄(預設:目前目錄)。 也會選擇 winapp.yaml 讀取 和 nuget.config 的位置,除非 --config-dir 被覆蓋。

選項:

  • --config-dir <path> - 包含 winapp.yaml 的目錄(預設:base-directory)

它的用途:

  • 讀取現有 winapp.yaml 配置
  • 下載/更新 SDK 套件至指定版本
  • 重新產生 C++/WinRT 標頭與二進位檔
  • 將可分享檔案儲存在全域快取目錄中

備註

對於 .NET 專案沒有winapp.yaml——SDK 版本會以PackageReference條目形式.csproj存在——所以winapp restore你可以自動執行dotnet restore。

範例:

# Restore from winapp.yaml in current directory
winapp restore

# Restore a specific project directory (reads ./my-project/winapp.yaml)
winapp restore ./my-project

自訂與私人 NuGet 訂閱源:

winapp init restore,並update透過 NuGet 下載 Windows SDK 和 Windows 應用程式 SDK 套件,並遵守你的標準nuget.config階層結構。 私有訂閱源與鏡像、訂閱憑證(包括憑證提供者)以及自訂 globalPackagesFolder 功能都運作,這些功能都適用於 dotnet restore。 若要完全從你自己的鏡像、繼承的來源恢復,並只加入你的來源 <clear /> :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="contoso" value="https://pkgs.dev.azure.com/contoso/_packaging/winsdk-mirror/nuget/v3/index.json" />
  </packageSources>
</configuration>

備註

對於原生專案,Winapp 會nuget.config從它所restoreinit/操作的目錄來解析:如有目錄參數--config-dir,否則為目前的目錄。 對於 .NET 專案,來源會來自專案本身nuget.config的階層,因為那是dotnet add packagedotnet restore用途,所以把私人串流的設定檔放在專案目錄或祖先檔裡。 外部的 --config-dir 階層會被報告並忽略,而不是默默選擇專案無法恢復的版本。 這些指令只對你信任的目錄執行,這點和 dotnet restore. 當設定多個來源時,使用 套件來源映射(Package Source Mapping )將每個套件釘選到一個串流。


更新

將套件更新到最新版本並更新設定檔。

winapp update [options]

選項:

  • --setup-sdks <stable|preview|experimental|none> - SDK 安裝模式: stable (預設)、 preview、 experimental或 none (跳過 SDK 安裝)

它的用途:

  • 讀取目前目錄中的現有 winapp.yaml 設定
  • 將所有套件更新至最新版本
  • 更新 winapp.yaml 檔案並加入新的版本號
  • 重新產生 C++/WinRT 標頭與二進位檔

範例:

# Update packages to latest versions
winapp update

# Update including experimental packages
winapp update --setup-sdks experimental

pack

從專案或已準備好的應用程式目錄建立 MSIX 套件。 需要目標目錄中、目前目錄中或隨選項傳遞Package.appxmanifest的清單檔案appxmanifest.xml(偏好--manifest且支援)。 (跑步 init 或 manifest generate 製作清單)

傳遞單一 .csproj 訊息即可建立專案並一次打包輸出(專案模式,請見下方 「打包專案 」)。 傳遞多個輸入資料夾以建立 .msixbundle 多架構發行版(詳見下方多 架構套件 )。

winapp pack <input-folder> [input-folder...] [options]

引數:

  • input-folder - 一個 .csproj 用於建置與打包的目錄(專案模式),或一個或多個包含要打包的應用程式檔案的目錄。 傳遞多個資料夾(例如 ./publish/x64 ./publish/arm64)來建立 MSIX 套件。 對於 sparse identity 套件,直接傳遞 sparse appxmanifest.xml 檔案而非資料夾(詳見下方 Sparse identity packages )。

選項:

  • --output <filename> - 輸出檔名。 對於單一封裝: <name>_<version>_<arch>.msix (退回到 <name>_<version>.msix、 <name>_<arch>.msix或 <name>.msix)。 對於叢: <name>_<version>_<arch1>_<arch2>.msixbundle。
  • --name <name> - 套件名稱(預設:來自清單)
  • --manifest <path> - 清單檔案路徑(Package.appxmanifest 偏好且 appxmanifest.xml 支援;預設:自動偵測)
  • --cert <path> - 簽署憑證路徑(啟用自動簽署)
  • --cert-password <password> - 憑證密碼(預設:「password」)
  • --generate-cert - 產生新的開發證書
  • --no-sign - 交付套件時未簽約,覆蓋任何專案簽署設定(例如商店提交或外部簽署流程)。 無法與 --cert 或 --generate-cert結合。
  • --install-cert - 將憑證安裝到機器
  • --publisher <name>- Publisher 用於憑證產生。 接受完整的 X.500 區分名稱或一個純名稱(自動包裝為 CN=<name>)
  • --self-contained- 捆綁 Windows 應用程式 SDK 執行環境
  • --skip-pri - 跳過 PRI 檔案產生
  • --executable <path> - 相對於輸入資料夾的可執行檔路徑(亦為 --exe)。 用來解析 $targetnametoken$ 清單中的佔位符。

Project 模式選項(需要輸入.csproj;被資料夾/套件/清單輸入拒絕):

  • --configuration <name> (-c) - 建置設定(預設: Release)
  • --arch <arch> - 目標架構: x64、、 arm64或 x86 (預設:目前的程序架構)
  • --framework <tfm> (-f) - 多目標專案的目標框架名稱
  • --no-build - 將現有建置輸出打包,無需重建
  • --no-restore - 跳過在施工前修復專案
  • --property <name=value> (-p) - MSBuild 資產,已轉交建設與評估(可重複)

註:對於 WinUI / EnableMsixTooling.csproj (MSIX 工具模式)專案模式,Windows 應用程式 SDK 擁有清單、入口點和 PRI 產生,因此 --manifest、 --executable、 會--skip-pri被拒絕——配置 <AppxManifest>、 專案的入口點及其在專案內的資源建置。 這三個選項仍然適用於資料夾輸入和一般(非 MSIX 工具) .csproj 專案模式。

它的用途:

  • 驗證並處理 Package.appxmanifest 檔案
  • $placeholder$解析清單中的標記(見下方 Manifest 佔位符)
  • 確保適當的框架相依性
  • 清單與登記並列更新
  • 如果清單目錄或輸入資料夾中缺少任何非影像檔案(例如應用程式擴充 manifest.json功能、設定檔),會自動發現並打包
  • 自動發現第三方 WinRT 元件並註冊其可啟用類別(詳見下方 WinRT 元件發現 )
  • 處理自包含的 WinAppSDK 部署
  • 如果有證書,請提供標誌套件

直接打包專案

當輸入為單一 .csproj時, winapp pack 會建構專案(使用上述選項),並將輸出封包——無需先另行建置或找到輸出資料夾。 這與 的專案模式相 winapp run呼應。

# Build MyApp in Release for arm64 and package + sign it in one step
winapp pack ./MyApp.csproj -c Release --arch arm64 --cert ./devcert.pfx

# Package an existing build output without rebuilding
winapp pack ./MyApp.csproj --no-build

# Select the target architecture with an exact RID instead of --arch
winapp pack ./MyApp.csproj -p RuntimeIdentifier=win-x64

目標架構來自 --arch,或是當你沒通過--arch時的孤立-p RuntimeIdentifier=<rid>(RID 會被保留並驅動整個組裝)。 同時通過 --arch 和 -p RuntimeIdentifier 則是衝突,會被拒絕。

專案必須以 package 應用程式EnableMsixTooling=truePackage.appxmanifest( 為 )建置;若以非 pack 應用程式WindowsPackageType=None建置,則沒有 MSIX 清單可打包,並winapp pack報告可操作錯誤。 資料夾、捆綁和稀疏清單輸入都沒變。

Project 模式產生單一.msix或僅.msixbundle有架構的模式(參見多架構套件)。 它不會產生 Store-upload 壓縮檔或資源分割(語言/規模)套件:明確-p UapAppxPackageBuildMode=StoreUpload-p AppxBundleAutoResourcePackageQualifiers=...或被拒絕,並附註直接執行原生 SDK 封包指令。

稀疏身份封包

當輸入是稀 疏 appxmanifest.xml 檔案 (在 <uap10:AllowExternalContent>true</uap10:AllowExternalContent><Properties>下宣告的檔案)而非資料夾時, winapp pack 會建立 純.msix 身份檔案——它只打包清單,沒有應用程式二進位檔或資產。 這是 稀疏包裝工作流程的第二步。

# Build a signed identity package from a sparse manifest
winapp pack ./sparse/appxmanifest.xml --cert ./devcert.pfx
  • 輸出預設為 <PackageName>.identity.msix 目前目錄中的 (覆寫為 --output)。
  • 簽署只有在 --cert 提供(或 --generate-cert)時才會發生。
  • 如果你改為傳遞一個清單宣告為 AllowExternalContent的資料夾,則依舊的資料夾打包行為,但winapp pack如果發現資產().ico//.png.jpg或二進位檔(.exe.dll//.so)會警告——對於稀疏套件,這些應該放在外部位置,而非內部。.msix

打包完成後,執行winapp embed-identity <exe>並在安裝程式中註冊該套件。Add-AppxPackage -Path <msix> -ExternalLocation <install-dir> 請參閱稀 疏包裝指南。

WinRT 元件發現

在打包時,會winapp pack自動掃描 NOR winapp.yaml 定義的 *.csproj NuGet 套件,針對第三方 WinRT 元件(例如 Win2D)。 它解析 .winmd 檔案以擷取可啟用的類別名稱,並定位其實作 DLL。 發現的條目登記如下:

  • 依賴框架 (預設):可啟用的類別會作為 <InProcessServer> 項目加入 Package.appxmanifest
  • 自包含--self-contained():可啟用類別嵌入於可執行檔中的並列(SxS)manifest 中

包裝時的占位符解決:

若清單屬性包含$targetnametoken$Executable:

  1. 若 --executable 提供(相對於輸入資料夾的路徑),則佔位符會被替換為指定的值
  2. 否則,會 winapp pack 掃描輸入資料夾根目錄中的 .exe 檔案——如果剛好找到一個檔案,會自動使用
  3. 如果找到零個或多個 .exe 檔案,會顯示錯誤提示你指定 --executable

範例:

# Package directory with auto-detected manifest
winapp pack ./dist

# Package with custom output name and certificate
winapp pack ./dist --output MyApp.msix --cert ./cert.pfx

# Package with generated and installed certificate and self-contained WinAppSDK runtime
winapp pack ./dist --generate-cert --install-cert --self-contained

# Package with explicit executable (resolves $targetnametoken$ in manifest)
winapp pack ./dist --executable MyApp.exe

多架構套件

當傳遞多個輸入資料夾時,會 winapp pack 建立 .msixbundle 一個包含 每個架構的 一個 .msix :

# Create unsigned bundle for Microsoft Store submission
winapp pack ./publish/x64 ./publish/arm64

# Create signed bundle for sideloading
winapp pack ./publish/x64 ./publish/arm64 --cert ./devcert.pfx

# Self-contained bundle
winapp pack ./publish/x64 ./publish/arm64 --self-contained --generate-cert

此指令會自動從主要執行檔的 PE 標頭偵測每個資料夾的架構,驗證各切片(身份、能力、相依)的一致性,並產生一個 <Name>_<Version>_<arch1>_<arch2>.msixbundle.

組合包的明確解決:

組合包中的每個切片都需要一個清單。 指令解析的顯現順序如下:

  1. --manifest <path> — 若另有指定,該單一清單用於所有切片。 ProcessorArchitecture每個切片都會自動更新,以符合偵測到的架構。

  2. 每個資料夾清單 — 如果每個輸入資料夾包含一個 Package.appxmanifest (或 appxmanifest.xml),該資料夾的清單會被用於其切片。

  3. 目前目錄的備援 — 如果某資料夾沒有清單,指令會在目前的工作目錄中尋找 並 Package.appxmanifest 使用該目錄(架構自動蓋章)。

在所有情況下,清單都會自動更新:佔位符被解析,相依性注入,並將 ProcessorArchitecture 強制設定為偵測到的架構。 解決後,跨切片驗證確保身份(名稱、版本、Publisher)、能力與相依性在所有切片間保持一致——僅ProcessorArchitecture可能有所不同。 切片中定義的套件版本會歸因於 MSIX 套件版本,除非是 0.0.0.0,否則會自動產生基於時間戳記的版本。

# Option 1: Single shared manifest (simplest for most projects)
# Place Package.appxmanifest in your project root and run from there
winapp pack ./publish/x64 ./publish/arm64

# Option 2: Explicit manifest path
winapp pack ./publish/x64 ./publish/arm64 --manifest ./src/Package.appxmanifest

# Option 3: Per-folder manifests (useful if slices have different app extensions)
# Each folder already contains its own Package.appxmanifest
winapp pack ./publish/x64 ./publish/arm64

建立除錯識別

建立應用程式身份以使用 稀疏封包來除錯。 exe 會留在原本的位置——Windows 透過 Add-AppxPackage -ExternalLocation 來與它關聯身份。

何時使用此方法與winapp run:當 exe create-debug-identity時使用(例如 Electron 應用程式,其中 electron.exe 是 ),node_modules或專門測試稀疏套件行為時使用。 對於大多數 exe 放在建置輸出資料夾的框架,請改用 winapp run — 它會註冊一個完整的鬆散版面套件並啟動應用程式。 完整比較請參閱 除錯指南 。

winapp create-debug-identity [entrypoint] [options]

引數:

  • entrypoint - 前往執行檔(.exe)或需要識別碼的腳本的路徑

選項:

  • --manifest <path> - 應用程式清單檔案的路徑,或 Package.appxmanifestappxmanifest.xml 為(預設:自動偵測 Package.appxmanifest 或 appxmanifest.xml 目前目錄中)
  • --no-install - 建立套件後不要安裝
  • --keep-identity - 保持清單身份 as-is,且不附加 .debug 套件名稱與應用程式 ID

它的用途:

  • 修改可執行檔的並排清單
  • 註冊稀疏套件以用於身份認證
  • 啟用偵錯需身分驗證的 API

範例:

# Add identity to executable using local manifest
winapp create-debug-identity ./bin/MyApp.exe

# Add identity with custom manifest location
winapp create-debug-identity ./dist/app.exe --manifest ./custom-manifest.xml

# Create identity for hosted app script
winapp create-debug-identity app.py

嵌入同一性

將桌面應用程式與其稀 疏身份套件 連接,方法是將該元素嵌入 <msix> 應用程式的並排(融合)清單中。 這是稀疏封包工作流程的第三步——它告訴 Windows 執行執行檔屬於哪個身份套件。

winapp embed-identity <target> [options]

引數:

  • target - 要更新的檔案。 自動偵測延伸:
    • .exe (EXE 模式)— 直接將元素嵌入 <msix> exe 的並排清單中,使用 mt.exe。
    • .xml / .manifest (XML 模式)— 插入或替換外部 SxS 清單檔案中的元素 <msix> (若不存在則建立)。 之後再重建你的應用程式,讓更新的清單嵌入二進位檔中。

選項:

  • --manifest <path> - 可讀取稀疏 appxmanifest.xml 識別碼(packageName、publisher、applicationId)的路徑。 若省略,指令先 sparse/ 搜尋目標旁邊的資料夾,接著在當前目錄,再搜尋目標目錄及當前目錄,搜尋 appxmanifest.xml。

範例:

# EXE mode — embed identity straight into the built exe
winapp embed-identity ./bin/Release/net8.0-windows/MyApp.exe

# XML mode — update a checked-in side-by-side manifest, then rebuild
winapp embed-identity ./app.manifest --manifest ./appxmanifest.xml

此指令為冪等指令:重新執行會替換任何已存在 <msix> 元素,而非重複。


資訊清單

產生並管理 Package.appxmanifest 檔案。

manifest 生成

從範本產生 Package.appxmanifest。

winapp manifest generate [directory] [options]

引數:

  • directory - 產生清單的目錄(預設:目前目錄)

選項:

  • --package-name <name> - 套件名稱(預設:資料夾名稱)
  • --publisher-name <name>- Publisher 特殊名稱(預設:CN=<目前使用者>)。 接受 X.500 DN,且元件為單值且逗號分隔(不支援多值 + RDN 與反斜線);裸名稱會自動包裝為 CN=<name>。
  • --version <version> - 版本(預設:「1.0.0.0」)
  • --description <text> - 說明(預設:「我的應用程式」)
  • --entrypoint <path> - 入口點執行檔或腳本
  • --template <type> - 範本類型: packaged (預設)或 sparse
  • --logo-path <path> - 標誌影像檔案路徑
  • --if-exists <Error|Overwrite|Skip> - 當清單檔案已存在於目標路徑時的行為(預設: Error)

範本:

顯現佔位符

生成清單使用以美元符號分隔的 $placeholder$ 標記,在打包時會自動解析:

預留位置 決心 範例
$targetnametoken$ 無副檔名的可執行檔名稱 Executable="$targetnametoken$.exe" → Executable="MyApp.exe"
$targetentrypoint$ Windows.FullTrustApplication 總是自動解決

這遵循 Visual Studio 專案範本的慣例,因此清單能跨工具可攜式。

占位符的解決方式:

  • winapp pack — 在打包過程中, $targetnametoken$ 透過選項 --executable 或自動偵測輸入資料夾中的單曲 .exe 來解決。 若發現多個(或零) .exe 檔案且 --executable 未指定,則會顯示錯誤。
  • winapp create-debug-identity — 當提供一個入點論元時, $targetnametoken$ 會從中解決。 若沒有入口點,可執行的佔位符必須已在清單中被解析。
  • winapp manifest generate --executable — 當 --executable 提供時,從執行檔中擷取了 manifest metadata(版本、描述)和圖示,但產生的 manifest 仍使用 $targetnametoken$.exe;此佔位符會在之後解決(例如 winapp pack 或 winapp create-debug-identity)。

PS: 將 $targetnametoken$ 保留在已簽入清單中,可以避免硬編碼執行檔名稱,並適用於 winapp pack 和 Visual Studio 建置。

範例:

# Generate standard manifest interactively
winapp manifest generate

# Generate with all options specified
winapp manifest generate ./src --package-name MyApp --publisher-name "CN=My Company" --if-exists overwrite

manifest 附加別名

在 Package.appxmanifest 中加入執行別名uap5:AppExecutionAlias()。 這讓使用者能透過輸入別名名稱,從命令列啟動已封裝的應用程式。

winapp manifest add-alias [options]

選項:

  • --name <alias> - 別名(例如 myapp.exe)。 預設:從 Executable 清單中的屬性推斷。
  • --manifest <path> - Package.appxmanifest 路徑(預設:搜尋目前目錄)
  • --app-id <id> - Application ID 以加入別名(預設:第一個應用程式元素)

它的用途:

  • 讀取清單並從 Executable 屬性推斷別名(保留像 $targetnametoken$.exe)
  • 如果還沒有命名空間宣告,會 uap5 新增
  • 新增一個<Extensions>區塊,目標應用程式元素內為<uap5:AppExecutionAlias>
  • 如果別名已經存在,請回報並成功退出

範例:

# Add alias inferred from Executable attribute (e.g. $targetnametoken$.exe)
winapp manifest add-alias

# Add alias with explicit name
winapp manifest add-alias --name myapp.exe

# Add alias to specific manifest
winapp manifest add-alias --manifest ./dist/Package.appxmanifest

清單更新資產

從單一來源映像產生所有必要的 MSIX 映像資產。

winapp manifest update-assets <image-path> [options]

引數:

  • image-path - 來源影像檔(PNG、JPG、SVG、ICO、GIF、BMP 等)的路徑

選項:

  • --manifest <path> - Package.appxmanifest 檔案路徑(預設:搜尋目前目錄)
  • --light-image <path> - 光源主題變體的路徑導向獨立來源影像

Description:

根據清單的資產參考,取得單一來源影像,產生完整的 MSIX 影像資產集合:

對於清單中提及的每項資產:

  • 5 種音階變體 — 基數(無後綴)、.scale-125、、 .scale-150.scale-200.scale-400

關於應用程式圖示(Square44x44Logo / AppList,44×44 底):

  • 14 種鍍甲靶尺寸變體 — .targetsize-{16,20,24,30,32,36,40,48,60,64,72,80,96,256}
  • 14 種未裝甲靶標尺寸變體 — .targetsize-{size}_altform-unplated

此外:

  • app.ico — 多解析度 ICO 檔案(16、24、32、48、256),用於殼整合。 如果在資產目錄中發現已有 .ico 檔案(例如 AppIcon.ico 來自專案範本),則會原地替換,而非建立重複檔案

使用 --light-image:

  • 輕主題目標大小變體 — .targetsize-{size}_altform-lightunplated (應用程式圖示)
  • 淺色主題比例變體 — .scale-{factor}_altform-colorful_theme-light (瓷磚、店面標誌)

SVG 支援: SVG 檔案完全支援作為原始影像。 它們會直接以向量形式呈現在每個目標尺寸下,在所有解析度下都能產生像素級完美的結果。 檔案必須透過 a viewBox 或 absolute width 以及 height 屬性來宣告自己的大小;百分比寬度若為 , viewBox 則不代表特定大小。 若來源宣稱兩者皆不存在,則會以空白資產取代被拒絕 SVG image has no usable dimensions 。

指令可按比例縮放影像,同時保持長寬比,必要時以透明背景置中。 資產會儲存到相對於清單位置的 Assets 目錄中。

範例:

# Generate assets with auto-detected manifest
winapp manifest update-assets mylogo.png

# Use an SVG source for best quality at all sizes
winapp manifest update-assets mylogo.svg

# Specify manifest location explicitly
winapp manifest update-assets mylogo.png --manifest ./dist/Package.appxmanifest

# Generate light theme variants from a separate image
winapp manifest update-assets mylogo.png --light-image mylogo-light.png

# Use the same image for both (generates all MRT light theme qualifiers)
winapp manifest update-assets mylogo.png --light-image mylogo.png

# With verbose output
winapp manifest update-assets mylogo.png --verbose

執行

從建置輸出資料夾建立一個鬆散的版面套件,使用 Windows.Management.Deployment.PackageManager API 註冊到 Windows,然後啟動應用程式——模擬完整 MSIX 安裝以供除錯。 回傳除錯器附加程序的 ID。

winapp run 運作模式為三種,會自動從輸入中選擇:

  • 資料夾模式 — 輸入為建置輸出資料夾(包含一個 Package.appxmanifest/AppxManifest.xml)。
  • Project 模式 — 輸入是一個 .csproj、一個.sln/.slnx解決方案,或是一個包含 的目錄。 winapp run 建立專案並啟動,支援 已打包 與 未打包的 WinUI 應用程式。 請參考下方的 Project 模式。
  • 單一檔案模式 — 輸入端是一個.cs基於 .NET 檔案的應用程式。 winapp run 建置它,從指令 #:property 產生清單,並以套件身份啟動。

Tip

模式選擇預設是靜音的。 如果你預期某個目錄會被當作專案,卻被當作建置-輸出資料夾,請重新執行—— --verbose 資料夾模式會回報為什麼選擇它(No .csproj/.sln/.slnx with a runnable app found in '<path>' — running it as a build-output folder.)。 只有當 a .csproj/.slnx/.sln有可執行的應用程式位於頂層時,目錄才會被建立為專案;它不會被遞迴搜尋。

這是大多數框架(.NET、C++、Rust、Flutter、Tauri)用於套件身份碼除錯的首選指令。 不像 create-debug-identity MSIX 會註冊一個稀疏套件,而是 winapp run 把整個資料夾註冊成一個鬆散的版面套件,就像真正的 MSIX 安裝一樣。 請參閱 除錯指南 以了解常見的除錯工作流程。

winapp run [<input>] [options]

引數:

  • input- 執行的應用程式:建置輸出資料夾(資料夾模式)、.cs基於 .NET 檔案的應用程式(單檔案模式)、.csproj專案、.sln/.slnx解決方案,或包含其中一列的頂層目錄(專案模式;目錄不會遞迴搜尋)。 用 . 來在目前的目錄中建置/執行專案。 可選 — 省略時預設為目前目錄 (匹配 dotnet run)。

選項:

  • --manifest <path> - Package.appxmanifest 路徑(預設:自動偵測輸入資料夾或當前目錄)
  • --output-appx-directory <path> - 輸出目錄,用於鬆散的佈局(預設: AppX 在輸入資料夾內)。 預設配置會移除不再包含在建置中的檔案;自訂目錄會保留額外的檔案。 需要乾淨版面時,使用全新的自訂目錄。
  • --args <string> - 命令列參數,傳遞給應用程式。 或者,使用 -- 後接參數以避免逃逸(例如, winapp run . -- --flag value)。
  • --no-launch - 僅建立除錯身份並註冊套件,而不必啟動應用程式
  • --with-alias - 啟動應用程式時,使用執行別名而非 AUMID 啟用。 應用程式在目前的終端機中運行,繼承了 stdin/stdout/stderr。 很少需要:已經有這種 OutputType=Exe 方式啟動的應用程式預設就是這樣啟動的。 Winapp 會在 AppX 佈局中將其分階段的清單中新增所需 uap5:ExecutionAlias 條件,因此不需要更改已簽入的清單;應用程式自行宣告的別名會被 as-is。 無法與 --no-launch、 --detach、 --without-alias、 --json或 合併。
  • --without-alias - 強制啟用 AUMID,讓原本會透過執行別名啟動的應用程式使用。 接著一個控制台應用程式會自動執行,且不會將任何列印到這個終端機。 不能與 --with-alias結合使用。
  • --debug-output - 從啟動應用程式中擷取 OutputDebugString 訊息及首次例外。 框架雜訊(WinUI、COM、DirectX)會從主控台輸出中被過濾;完整的日誌檔案會記錄所有內容。 如果應用程式當機,會自動擷取一個迷你傾印並分析,顯示例外類型、訊息和堆疊追蹤,並附帶原始檔案:行號(從建置輸出資料夾中的 PDB 解析)。 管理型(.NET)當機可即時分析,無需外部工具。 原生(C++/WinRT)當機時會顯示模組名稱和偏移量。 當當機的應用程式是 WinUI 3 應用程式(Microsoft.UI.Xaml.dll 已載入)時,會自動執行額外的 stowed-exception 分流通道,以顯示原始 HRESULT、其 ErrorContext 鏈及完整的原生 XAML 派遣堆疊;所需的除錯器元件會在首次使用時下載(參見 除錯,可透過 WINAPP_DBGTOOLS_DIR 環境變數覆寫)。 同一時間只能連接一個除錯器,因此無法同時使用其他除錯器(如 Visual Studio、VS Code)。 如果需要附加不同的除錯器,請使用 --no-launch 。 不能與 --no-launch結合使用。 不能與 --json結合使用。
  • --symbols - 從 Microsoft Symbol Server 下載 PDB 符號,提供更豐富的原生當機分析及已解析的函式名稱。 僅搭配 --debug-output使用。 若省略且發生原生當機,輸出會建議新增此旗標。 此旗標也改善了 WinUI 3 應用程式的收納例外分流堆疊。 首先執行時下載符號並快取到本地;後續執行會使用快取。
  • --unregister-on-exit - 應用程式退出後取消註冊開發套件。 只會移除在開發模式下註冊的套件。 不能與 --no-launch結合使用。
  • --detach - 啟動應用程式後立即返回,無需等待它退出。 對於需要在啟動後與應用程式互動的 CI/自動化來說很有用。 本地運行會印製 PID;目標執行,列印有範圍的 UI 目標。 JSON 包含 PID 和目標範圍。 無法與 --no-launch、 --debug-output、 --with-alias、 --unregister-on-exit或 合併。
  • --clean - 在重新部署前移除現有套件的應用程式資料(LocalState、設定等)。 預設情況下,應用程式資料會在重新部署過程中被保留。
  • --json - 輸出格式為 JSON 供程式化使用(例如 CI/自動化)。 --detach用來捕捉 PID。 無法與 --with-alias 或 --debug-output結合。
  • --on <target> - 先在主機上建置,然後註冊並執行目標。 目前支援 sandbox,且沒有回頭到本地執行。 在後續介面指令中使用 --detach 之前。 沙盒 --debug-output 需要一個打包好的應用程式。 請參閱 Windows 沙盒執行以了解設定、執行時支援及分離應用程式壽命。

應用程式資料持續性:

預設情況下,winapp run重新部署時會保留應用程式的資料(LocalState、RoamingStateSettings等)。 如果你的應用程式在套件上下文中寫入資料ApplicationData.Current.LocalFolderEnvironment.GetFolderPath(SpecialFolder.LocalApplicationData),這些資料會在呼叫間winapp run存活。

當你需要重新開始時使用 --clean (例如重置損壞狀態或測試首次執行行為)。

它的用途:

  • 定位或產生 Package.appxmanifest
  • 使用鬆散的版面套件建立並註冊除錯身份
  • 計算應用程式使用者模型識別碼(AUMID)
  • 以註冊身份啟動應用程式(除非 --no-launch 特別指定)
  • 列印程序 ID(PID)以供除錯器附加

範例:

# Register debug identity and launch app from build output
winapp run ./bin/Debug

# Launch with custom manifest and arguments
winapp run ./dist --manifest ./out/Package.appxmanifest --args "--my-flag value"

# Pass arguments after -- to avoid escaping (equivalent to --args)
winapp run ./bin/Debug -- --my-flag value

# Specify output directory for loose layout package
winapp run ./bin/Release --output-appx-directory ./AppXDebug

# Register identity without launching
winapp run ./bin/Debug --no-launch

# Launch via execution alias (console apps run in current terminal)
winapp run ./bin/Debug --with-alias

# Launch and capture OutputDebugString messages and crash diagnostics
winapp run ./bin/Debug --debug-output

# Download native symbols for richer crash analysis (C++/WinRT crashes)
winapp run ./bin/Debug --debug-output --symbols

# Combine with execution alias to debug console apps inline
winapp run ./bin/Debug --with-alias --debug-output

# Run and automatically clean up registration on exit
winapp run ./bin/Debug --with-alias --unregister-on-exit

# Launch and detach immediately (useful for CI/automation)
winapp run ./bin/Debug --detach

# Detach with JSON output (returns PID for scripting)
winapp run ./bin/Debug --detach --json

# Wipe application data (LocalState, settings) and start fresh
winapp run ./bin/Debug --clean

Project 模式(.NET SDK 專案)

當輸入為 .csproj、 、/.slnx.sln解決方案或包含 .的winapp run目錄時,會以dotnet build 建置專案並啟動。 它支援已打包與未封裝的 WinUI 應用程式,並在啟動前安裝符合架構的 Windows 應用程式 執行環境。

解決方案輸入:指向winapp run一個.sln/.slnx(或包含該方案的目錄——解決方案比散落.csproj檔案更受青睞),它會解析可執行的應用程式專案,然後用定義的兄弟Solution*屬性來建置,$(SolutionDir)讓依賴這些物件的專案能像 Visual Studio 一樣建置。 解決規則:

  • 自動選擇時會跳過測試專案,因此包含應用程式及其測試的解決方案會自動解析成應用程式,無需--project額外需求。 (WinUI 測試專案本身就是一個打包的應用程式,因此僅靠輸出型別無法區分它。)
  • 如果唯一可執行的專案是測試專案,它就會執行。
  • 如果存在多個可執行的應用程式專案, winapp run 則不會猜測新創專案——而是在列出候選項目時出錯。 使用 --project <name> 選擇功能,這點總是被遵守,包括選擇測試專案。

封裝與未封裝會自動從專案的有效 WindowsPackageType MSBuild 屬性中偵測(絕非從顯現狀態中偵測):

  • Packaged (WindowsPackageType=MSIXWinUI 封裝預設)— 建置後將建置輸出註冊為鬆散版面套件,並透過 AUMID(與資料夾模式相同的流程)啟動。
  • Unpackaged (WindowsPackageType=None) — 建置,確保安裝依賴框架的 Windows 應用程式 執行環境,然後直接啟動建置.exe版本。 強制執行為帶有 -p WindowsPackageType=None的封裝專案。

Project 模式需要 .NET SDK 8.0.100 或更新版本(適用於 MSBuild--getProperty)。

原生 AOT:在 project 檔案的<Project>元素中加入這個屬性群組,然後新增--aot:

<PropertyGroup>
  <PublishAot>true</PublishAot>
</PropertyGroup>
winapp run . --aot
winapp run . --aot -c Release

--aot支援 x64 與 ARM64 專案,並需使用 .NET SDK 8.0.300 或更新版本。 它會以專案的 AOT 設定執行 dotnet publish ,然後啟動該輸出;用於 -p PublishAot=true 一次性覆蓋。 它不執行獨立的執行時認證,且無法與 --no-build 或 --manifest合併使用。

對於使用套件身份但未產生 MSIX 佈局的應用程式,請將或包含Package.appxmanifestappxmanifest.xml在專案的發佈輸出中。 Winapp 會用該清單分階段發佈的檔案。 如果兩個名字都出現,winapp 會停止而不是選擇其中一個;移除過時的清單,並設定專案只發布預期清單。

Project 模式選項(資料夾模式中除非特別註明,否則忽略):

  • -c, --configuration <name> - 建構配置。 預設值:Debug。 (單列模式也同樣受到尊重。)
  • --arch <x64|arm64|x86> - 目標架構。 預設:目前的程序架構。 決定建置 RID 與 Windows 應用程式 執行時架構,並在有效建置需要時選擇相符的平台相關發佈設定檔。 (單列模式也同樣受到尊重。)
  • -r, --runtime <rid>- 目標 .NET 執行時識別碼(例如 win-x64)。 Project 模式僅使用 RID 架構,始終建立標準win-<arch>架構,並拒絕非 Windows RID(例如 linux-x64)。 其架構會 --arch 覆蓋並選擇所需的發佈設定檔。 (在單檔案模式下也會被尊重,該模式會覆寫檔案宣告的 。#:property RuntimeIdentifier
  • -f, --framework <tfm> - 多目標專案的目標框架名稱(例如 net10.0-windows10.0.26100.0)。 (單檔案模式拒絕 — 請使用 #:property TargetFramework=...。)
  • --project <name-or-path> - 當輸入為解決方案().sln/.slnx或包含多個可執行應用程式專案的目錄時,選擇要啟動的專案(依專案名稱或路徑)。 (單檔案模式被拒絕—— .cs 檔案式應用程式本身就是專案。)
  • --no-build - 跳過建造,直接執行現有的建置輸出(仍會評估輸出屬性)。 (單列模式也同樣受到尊重。)
  • --no-restore - 在建置或 Native AOT 發佈前跳過還原。 (單列模式也同樣受到尊重。)
  • --aot- 執行專案已設定的 .NET Native AOT 發佈。 需要有效 PublishAot=true。 在資料夾和單檔模式下被拒絕。
  • -p, --property <Name=Value> - MSBuild 物業,會同時轉交給建造單位及物業評估。 -p重複多個屬性;在值中使用%3B字%2C面上的分號或逗號。 (在單檔模式下也被使用,因為這是唯一能設定 TargetFramework的方式。)

建置輸出與冗長度: 一般專案執行會使用 dotnet build,然後評估建置輸出。 還原並即時建立輸出串流,並以已驗證的串流 URL 的憑證進行遮蔽。 Winapp --aot使用 dotnet publish; --verbose 顯示發佈指令及已解析路徑。 請使用以下冗長選項來控制顯示的內容:

Flag dotnet 冗長度 補充
(預設) minimal —
--verbose minimal Winapp 的建置決策追蹤
--quiet quiet —

原生 AOT 會即時發布輸出串流。 在 --json、還原/建置調用和子輸出下,會去 stderr,這樣 stdout 就保持純 JSON 格式。 在 --quiet下,呼叫會被抑制,dotnet 的靜默還原/建置輸出會被路由到 stderr,讓 stdout 保持乾淨。 原生 AOT 發佈輸出在任一選項下也會被轉到 stderr。

選項適用性:身份/鬆散排版選項(--manifest, , --output-appx-directory--no-launch, --unregister-on-exit--with-alias--clean--executable, , ) 僅適用於已打包的應用程式。 未封裝的應用程式(沒有 MSIX 套件)會被拒絕,並顯示明顯錯誤。 啟動/除錯選項(--args--/, , --detach--debug-output, --symbols, --json) 在兩者中都能使用。

Project 模式範例:

# Build and run the project in the current directory (input defaults to ".")
winapp run

# Run a specific project
winapp run ./src/MyApp/MyApp.csproj

# Build and run from a solution (resolves the runnable app project, defines $(SolutionDir))
winapp run ./MyApp.sln

# Pick a startup project when the solution has more than one runnable app
winapp run ./MyApp.sln --project MyApp

# Release build for arm64
winapp run . -c Release --arch arm64

# Publish and run the Release configuration with Native AOT
winapp run . --aot -c Release

# Force an unpackaged run of a packaged project
winapp run . -p WindowsPackageType=None

# Run the existing build output without rebuilding, and capture crash diagnostics
winapp run . --no-build --debug-output

# Show winapp's build decision traces (dotnet build stays at minimal verbosity)
winapp run . --verbose

# Launch and detach (prints PID), forwarding args to the app
winapp run . --detach -- --my-flag value

單檔模式(.NET 檔案型應用程式)

.NET 10 允許你執行一個.cs沒有專案檔案的檔案,並在頂部設定#:指令。 指向 winapp run 那個檔案,它會建立應用程式,產生 appxmanifest,並 以套件身份 啟動——所以 Windows.ApplicationModel.Package.Current 能運作,應用程式會得到真正的 AUMID 和開始選單項目,而只需要身份的 API(應用程式通知、 ApplicationData裝置上的 AI)也能正常運作。

shell 整合如協定處理器、檔案關聯、共享目標及啟動任務需要宣告 <Extensions> 的條目,而產生的清單中不包含此條目。 要補充,請自行撰寫你的manifest——詳見下方 「帶上你自己的manifest 」。

winapp run counter.cs

或者用普通的dotnet run水——詳見下方「與dotnet run水線」相關說明。

你不需要撰寫清單。 請用指令描述套件 #:property :

#:package Microsoft.UI.Reactor@0.1.0-preview.13
#:property OutputType=WinExe
#:property TargetFramework=net10.0-windows10.0.22621.0
#:property UseWinUI=true
#:property RuntimeIdentifier=win-x64

#:property WinAppPackageName=com.contoso.counter
#:property WinAppDisplayName=Contoso Counter
#:property WinAppDescription=Counts things, one click at a time
#:property Version=1.2.3

using static Microsoft.UI.Reactor.Factories;
ReactorApp.Run<MyApp>("Hello");

顯現性屬性。 所有這些課程皆為可選;每個選項都回到一個合理的預設:

房產 組 預設
WinAppPackageName Identity/@Name (套件身份) 檔名(sanitized to ,sanitized) [-.A-Za-z0-9]加上檔案路徑的短雜湊值(counter.cs → counter-a1b2c3d4)
WinAppDisplayName 名稱在開始與設定中顯示 檔名(不含副檔名)
WinAppPublisher Identity/@Publisher CN=<your Windows user name>。 裸名稱會包裝為 CN=<name>。
WinAppVersion Identity/@Version $(Version),正規化(見下文)
WinAppDescription 安裝時和設定中顯示的描述 顯示名稱
WinAppCapabilities 宣告能力,分隔於 ; 或 , 沒有

Version. 一個套件版本必須是四個數字,每個數字為 0–65535。 WinAppVersion (或者,如果你不設定,則是標準 Version 性質)被正規化為:任意 -preview/-rc 後綴會被省略,缺少的元件會被填入零,因此 #:property Version=1.2.3-preview.4 變成 並將 1.2.3.0 你的組合語言版本與套件版本同時設定。 無法調整的數值——例如超過65535的元件,或超過四個元件——會以 錯誤拒絕 ,而非默默更改。

Capabilities

你的應用程式與身份完全信任,這滿足只需打包應用程式的 API。 但有些 API 仍會限制已宣告的能力——例如 Windows 的 AI API 是常見的情況。 (shell 整合如協定處理器和檔案關聯是第三種情況:這些需要作者的 <Extensions> 條目,而非能力,因此請使用 您自己的清單 。)

#:property WinAppCapabilities=systemAIModels

這就是 Phi Silica 和其他裝置端模型 API 從清單中所需的全部。 透過將多個名稱分開申報:

#:property WinAppCapabilities=systemAIModels;internetClient;microphone

Winapp 會將每個 S 寫入它實際需要的元素和 XML 命名空間,宣告該命名空間,並在需要新命名時再啟動 MaxVersionTested 。 這比聽起來更重要:能力分散在多個不同元素中,而上述同一份清單變成三種 不同的 形狀——

<systemai:Capability Name="systemAIModels" />
<Capability Name="internetClient" />
<DeviceCapability Name="microphone" />

Winapp 知道這些名字都是為你寫的。 對於其他內容——受限集合會隨時間增長——請自行用命名空間前綴來修正:

前綴 發射
rescap: <rescap:Capability> — 有限能力
uap:、uap6:、uap7:、uap11: <uap*:Capability>
systemai: <systemai:Capability>
device: <DeviceCapability>
app: <Capability> 在預設命名空間中
#:property WinAppCapabilities=rescap:broadFileSystemAccess

未識別的裸名稱會被拒絕,錯誤命名這些前綴,而非猜測——錯誤的命名空間中發出的能力會產生 Windows 拒絕註冊或默默接受但未授予的 manifest。

帶上你自己的清單

如果你需要屬性未涵蓋的東西——像是協定處理器、檔案關聯、執行別名——就寫一份清單,並且 winapp run 會逐字使用,而不是產生清單。 它從以下位置接續,順序如下:

  1. --manifest <path> 在命令列。
  2. #:property WinAppManifestPath=<path> 在檔案裡 .cs 。
  3. 一個清單放在檔案旁邊 .cs ,名稱( <filename>.appxmanifest 例如 counter.appxmanifest 旁邊 counter.cs)。

只有該檔案名稱會自動被擷取。 同一資料夾中的 A Package.appxmanifest 或 appxmanifest.xml 會被刻意忽略——多個 .cs 檔案可以共用一個資料夾,採用共用名稱會悄悄地以另一個應用程式的身份執行。 若要使用一個清單來管理多個檔案,請明確命名為 --manifest 或 WinAppManifestPath。

否則 a Package.appxmanifest 會被生成到建置輸出中,連同預設的圖片素材,並且每次執行都會重新整理。

Options. 所有資料夾模式選項都有效:, --no-launch, , --no-build-p/--property-c/--configuration--no-restore--/--json--args--executable--manifest--without-alias--clean--output-appx-directory--detach--debug-output--symbols--unregister-on-exit--with-alias

Tip

預設情況下,主控台應用程式會列印到你的終端機。 透過 AUMID 啟動的打包應用程式沒有主控台,所以只有主控台上的應用程式會正常執行,且不會印出任何東西。 Winapp 避免了這種情況: OutputType=Exe 應用程式會透過執行別名啟動,繼承該終端機的 STDIN/STDOUT/STERR。 你仍然會取得包裹身份,且不必主動要求:

winapp run counter.cs

直接跳過 --without-alias 強制啟用 AUMID — 這樣應用程式就不會有主控台,這裡什麼都不列印。 視窗應用程式(WinExe)會顯示視窗,所以會保留 AUMID 啟用;如果你想在這終端機啟用,就跳過 --with-alias 吧。 為了在檔案中固定選擇,而不是每個命令列,請設定與 a .csproj 使用的相同屬性:

#:property WinAppRunUseExecutionAlias=false

winapp 宣告的別名是以套件族名命名,並帶有winapp-前綴——因此com.contoso.counter發佈 CN=You 會 。winapp-com.contoso.counter_gspb8g6x97k2t.exe 那個尾端是 Windows 推導的出版商雜湊值,所以兩個在不同出版商下共用名稱的應用程式,仍然會有不同的別名。 前綴會讓名稱中排除真正的指令:應用程式在 中 python.cs 會取得 winapp-… 別名,絕不會 python.exe。 如果你自己寫清單,你在清單上宣稱的別名會被用 as-is,Winapp 不會新增任何東西。

這只適用於別名。 註冊本身是根據套件 名稱來進行的,所以在另一個發行商下執行第二個宣告相同 WinAppPackageName 功能的應用程式,會取代第一個註冊,而不是並存。 如果你想同時註冊,可以給每個應用程式取一個名字。

winapp run 它會印出它註冊的別名,所以你不用計算雜湊值就能找到它。

別名是你 PATH 上的一個指令,只要包裹還在註冊狀態就會持續。 如果其他套件已經擁有這個名稱,Winapp 會這麼說。 當它推斷出別名時,它會透過 AUMID 啟動,而不是啟動錯誤的應用程式;當你明確要求一個——用 --with-alias 或 #:property WinAppRunUseExecutionAlias=true ——它就會失敗,而不是悄悄地做其他事情。

兩種專案模式 選項不 適用,因為基於檔案的應用程式會自行設定。 它們會被拒絕,並以訊息指示指示要改用:

Option 改用
-f/--framework #:property TargetFramework=net10.0-windows10.0.22621.0
--project 什麼都沒有——檔案.cs就是專案

--arch 並且 -r/--runtime 像專案模式一樣運作。 當你兩者都不通過時,winapp 會依照你的機器架構建置——這正是自包含的 Windows 應用程式 SDK 應用程式所需要的,因為沒有 Winapp SDK 會AnyCPU以 建置並失敗WindowsAppSDKSelfContained requires a supported Windows architecture。 檔案中的 A #:property RuntimeIdentifier=win-arm64 被尊重;明確 --arch/--runtime 的 A 會覆蓋它。

打包與非打包兩種方式都能正常運作,從實際WindowsPackageType效果中偵測到的,就像專案模式一樣:預設會註冊一個鬆散的版面並以身份啟動,同時#:property WindowsPackageType=None建立應用程式,安裝對應的 Windows 應用程式 執行環境,然後直接啟動。.exe (封裝應用程式會透過執行別名或 AUMID 啟用啟動——詳見上方主控台說明;該選擇與是否封裝是分開的。)身份選項(--no-launch, , --without-alias--with-alias, --manifest--clean--unregister-on-exit) --output-appx-directory僅適用於已打包的應用程式。

與 dotnet run

你根本不需要打字 winapp 。 參考 Microsoft.Windows.SDK.BuildTools.WinApp 檔案中的套件,直接 dotnet run 給出相同的套件啟動:

#:package Microsoft.Windows.SDK.BuildTools.WinApp@*
#:property OutputType=Exe
#:property TargetFramework=net10.0-windows10.0.19041.0

System.Console.WriteLine(Windows.ApplicationModel.Package.Current.Id.FamilyName);
dotnet run counter.cs

該套件的 MSBuild 目標會將執行重定向到 winapp,Winapp 會打包、註冊並啟動剛建置的 dotnet run 應用程式——不會重建。 清單處理方式不變:winapp 解決方式與 winapp run,所以 #:property WinAppManifestPath=… 旁邊的 a <filename>.appxmanifest.cs 都會被尊重(參見 Bring your own manifest), Package.appxmanifest 目錄範圍仍被忽略,否則會從指令 #:property 產生並每次執行重新整理。

重定向必須符合以下兩個條件:

指令 原因為何
#:package Microsoft.Windows.SDK.BuildTools.WinApp@* 在這個包裡執行重定向飛船的目標
#:property TargetFramework=net10.0-windows… net10.0一般檔案會保持原樣,因此會執行未封裝的狀態

新增 #:property WindowsPackageType=None 檔案時也會保持檔案不變: dotnet run 然後直接執行, .exe 無需識別碼。 如果你想先安裝對應的 Windows 應用程式 執行環境,請使用winapp run未封裝路徑。

設定完全退出重定向,並依WinAppRun*配置描述的屬性來塑造啟動——例如:#:property EnableWinAppRunSupport=false

#:property WinAppRunUnregisterOnExit=true

如果你 dotnet run 預期身份時是無封裝執行應用程式,問問 MSBuild 為什麼。 使用 dotnet build,而非 dotnet msbuild — 僅 dotnet build 綜合檔案型應用程式所編譯的虛擬專案:

dotnet build counter.cs -t:WinAppRunSupportInfo

單檔模式需要 .NET SDK 10.0.300 或更新版本。

註冊號碼會延續到演出結束後。 winapp run counter.cs 應用程式退出後,套件會保持註冊狀態,就像資料夾和專案模式一樣——這樣 LocalState 才能存活下來,重複執行同一檔案時會重複使用相同的身份,而不是堆積大量註冊。 Winapp 第一次註冊應用程式時就這麼說,並 winapp unregister 取 .cs 出

# Remove the registration (resolves the same identity `winapp run` registered)
winapp unregister counter.cs

# Or remove it as soon as the app exits
winapp run counter.cs --unregister-on-exit

winapp unregister counter.cs不需要 manifest 路徑:它以相同方式run評估檔案的#:property值,並只從該檔案的建置輸出中移除註冊的套件。 同名應用程式從不同資料夾註冊,除非你通過 --force,否則會被拒絕。 如果該跑動使用了塑造身份或版面的選項,則將相同的選項傳遞給 unregister:

winapp run counter.cs -p WinAppPackageName=com.contoso.alt
winapp unregister counter.cs -p WinAppPackageName=com.contoso.alt

winapp run counter.cs -c Release --arch arm64
winapp unregister counter.cs -c Release --arch arm64

-p覆蓋檔案本身的指令,Directory.Build.props.cs旁邊的 can WinAppPackageName 鍵 or $(Configuration)$(RuntimeIdentifier) —— 這樣每個指令都可以改變哪個套件要註冊。

一旦 SDK 的臨時輸出被清理完畢,就 winapp unregister counter.cs 無法再確認註冊是否來自該檔案,於是會跳過它—— winapp unregister --prune 用來清除已刪除的註冊,或 --force 是移除特定檔案。 如果執行時使用 --output-appx-directory了 ,則將同一個目錄傳給 , unregister 讓它能辨識該版面配置。

自訂輸出路徑也是一樣:所有權會從 SDK 的標準 <root>\bin\<configuration> 版面確認,因此用 -p OutputPath=<somewhere-else> 建置的執行無法與其原始檔案匹配。 unregister 跳過它而不是猜測更廣泛的目錄—— --output-appx-directory用 ,或使用 --force。

單列範例:

# Build and run a file-based app with package identity
winapp run counter.cs

# Register identity without launching (e.g. to attach Visual Studio)
winapp run counter.cs --no-launch

# Release build, detached, printing the PID as JSON
winapp run counter.cs -c Release --detach --json

# Capture OutputDebugString output and crash diagnostics
winapp run counter.cs --debug-output

# Forward arguments to the app
winapp run counter.cs -- --verbose --input data.json

# Wipe the app's LocalState and start fresh
winapp run counter.cs --clean

# Remove the package it registered
winapp unregister counter.cs

備註

預設身份包含檔案路徑的短雜湊值——counter.cs變成類似counter-a1b2c3d4的——所以counter.cs兩個不同資料夾中的檔案是不同的應用程式,並各自保留自己的設定。LocalState 雜湊值是從路徑衍生出來的,所以它能經得起編輯和重跑,只有移動檔案才會改變。 設定 #:property WinAppPackageName=<name> 為自己選擇穩定身份;其標準化為允許的範圍 Identity/@Name ——刪除外 [-.A-Za-z0-9] 面的字元,少於 3 字元的名稱填充 1,且結果上限為 50 字元,因此 My App 註冊為 MyApp。 不管怎樣,開始選單和設定顯示的是你的 WinAppDisplayName (預設檔名),而不是身份。 身份設定永遠是針對你的使用者帳號,因此不會與同一台機器上的另一個使用者發生衝突。

MSBuild 屬性(NuGet 套件):

使用 Microsoft.Windows.SDK.BuildTools.WinApp NuGet 套件時,dotnet run 會自動呼叫 winapp run。

之後 dotnet run 寫的所有內容都會傳到 你的應用程式,就像沒有套件時一樣。 請用以下 MSBuild 屬性設定啟動器:

# Goes to your app. `--` is optional here, but required when the flag is also a
# `dotnet run` option (--configuration, --framework, --project, -c, -f, -r, ...),
# otherwise the SDK claims it and your app never sees it.
dotnet run --devtools
dotnet run -- --devtools
dotnet run -- --configuration Release

# Configures WinApp; --devtools still reaches your app
dotnet run -p:WinAppRunDetach=true --devtools

以下 MSBuild 屬性可在你的 .csproj 控制行為中設定:

房產 預設 說明
EnableWinAppRunSupport true 啟用或停用跑步支援功能
WinAppLaunchArgs (空白) 應用程式上市時應提出的論點
WinAppRunUseExecutionAlias 從應用程式推斷 透過執行別名啟動而非 AUMID 啟動。 未設定的情況下,winapp 推斷出:主控台應用程式使用別名使其輸出到達終端機,視窗應用程式則使用 AUMID。 設定 true 或 false 自己決定。
WinAppRunNoLaunch false 只註冊身份,且不啟動
WinAppRunDebugOutput false 捕捉 OutputDebugString 訊息與首次例外。 一次只能連接一個除錯器(防止 VS/VS 程式碼使用)。 用 WinAppRunNoLaunch 來接一個不同的除錯器。
WinAppRunDetach false 啟動後立即返回,不要等應用程式退出。 列印PID。
WinAppRunUnregisterOnExit false 應用程式退出後,開發套件會取消註冊
WinAppRunClean false 在重新部署前,先移除現有套件的應用程式資料(LocalState、設定)
WinAppRunSymbols false 從 Microsoft Symbol Server 下載符號,以獲得更豐富的原生崩潰分析。 只有在 時 WinAppRunDebugOutput才有影響。
WinAppRunExecutable (空白) 相對於 build-output 資料夾的執行檔路徑。 當清單包含 $targetnametoken$ 且輸出資料夾有多個 .exe時,請使用。
WinAppRunArgs (空白) 原始參數附加於 winapp run 命令列,用於沒有專用屬性的選項(例如 --verbose)。 附於上述每個屬性後。

互斥的設定。 WinAppRunNoLaunch 而且 WinAppRunDetach 每個特性描述的發射行為都不同,因此會與其他發射屬性及彼此產生衝突。 設定衝突對會使得 --X and --Y cannot be used together:

房產 無法與
WinAppRunNoLaunch WinAppRunDetach、WinAppRunDebugOutput、WinAppRunUnregisterOnExit
WinAppRunDetach WinAppRunNoLaunch、WinAppRunDebugOutput、WinAppRunUnregisterOnExit

WinAppRunUseExecutionAlias 故意 不 在那個名單裡,無論向哪個方向。 false 要求啟動AUMID,該系統已用於無發射與分離; true 當兩者都被設定時,則不會套用,因為執行別名需要一個被追蹤且正在執行的程序。 所以一個能簽入 <WinAppRunUseExecutionAlias>true</WinAppRunUseExecutionAlias> 的專案仍然能 dotnet run -p:WinAppRunDetach=true在 , 下透過 AUMID 啟動,而不是失敗。

WinAppRunUseExecutionAlias, , WinAppRunDebugOutput和 WinAppRunUnregisterOnExit 可以彼此組合。 WinAppRunClean, WinAppRunSymbols, WinAppRunExecutable, , WinAppLaunchArgs 且沒有任何限制。 WinAppRunArgs 本身沒有額外限制,但通過它的交換器會像其他交換器一樣被檢查,因此 WinAppRunArgs="--detach" 仍與 衝突 WinAppRunNoLaunch。

<PropertyGroup>
  <WinAppRunUseExecutionAlias>true</WinAppRunUseExecutionAlias>
  <WinAppRunDebugOutput>true</WinAppRunDebugOutput>
</PropertyGroup>

取消註冊

取消註冊一個側載開發套件。 僅移除已註冊於開發模式的套件(例如 via winapp run 或 create-debug-identity)。 儲存安裝或 MSIX 安裝的套件永遠不會被移除。

winapp unregister [input] [options]

引數:

  • input- 前往一個 .NET 檔案應用程式(單一.cs)的路徑,其套件應未註冊。 其身份的解析方式與解析相同 winapp run ——若應用程式有作者清單(若有),則由其值解析 #:property ——因此不需要清單路徑。 省略 --manifest 使用或自動偵測目前目錄中的清單。 無法與 --manifest合併,因為 包名稱不同且可解析為不同。

選項:

  • --manifest <path> - Package.appxmanifest 路徑(預設:自動偵測當前目錄)
  • --force - 僅本地除名時,跳過安裝位置目錄檢查,即使套件是從不同專案樹註冊,也要取消註冊。 以 ;目標所有權檢查無法被繞過時被拒絕 --on。
  • --on <target> - 移除 Windows 應用程式擁有的匹配開發註冊,該註冊號碼從 sandbox不是此機器中移除。 需要清單,且不支援 --force。 請參見 沙盒應用程式清理。
  • --prune - 移除所有已刪除檔案的開發模式註冊。 無法與輸入 --manifest, , --property--configuration, --arch, --runtime, --output-appx-directory結合。
  • -p, --property <Name=Value> - MSBuild 屬性,用於解析 .cs 檔案型應用程式的身份。 可重複。 傳遞執行時相同的影響身份的屬性(例如 -p WinAppPackageName=...),因為命令列屬性會覆蓋檔案本身 #:property 的指令。 只適用於輸入 .cs 。
  • -c, --configuration <name> - 用於解析 .cs 檔案型應用程式身份時所使用的建置設定。 預設值:Debug。 傳遞與運行相同的配置:a Directory.Build.props 在罐旁,.cs條件WinAppPackageNameWinAppManifestPath設定為 $(Configuration)。 只適用於輸入 .cs 。
  • --arch <x64|arm64|x86> - 用於解析 .cs 檔案型應用程式身份的目標架構。 預設:目前的程序架構。 傳遞與執行相同架構的系統,因為身份也可以被鍵控。$(RuntimeIdentifier) 只適用於輸入 .cs 。
  • -r, --runtime <rid>- 目標 .NET 執行時識別碼(例如 win-x64),用於解析.cs檔案型應用程式身份。 僅使用其架構,且覆蓋 --arch。 只適用於輸入 .cs 。
  • --output-appx-directory <path> - 該套件註冊的 AppX 版面目錄。 只有當執行使用時 --output-appx-directory才需要,因為執行選項的套件記錄中沒有任何配置顯示。
  • --json - 輸出格式化為 JSON

它的用途:

  • 決定套件名稱——可根據 .cs 檔案解析身份,或透過讀取清單
  • 同時搜尋 {name} 和 {name}.debug 套件(除錯變體由 create-debug-identity)
  • 驗證每個套件是否已註冊在開發模式(IsDevelopmentMode == true)
  • 驗證該套件是否屬於你指定的應用程式(除非 --force)——其安裝位置必須位於你指定的目錄下方:檔案 .cs 本身的建置輸出、清單目錄、目前目錄,或明確的 --output-appx-directory。 無法解析安裝位置(檔案被刪除)的套件會 被跳過,因為僅有身份無法證明擁有權:兩個同時設定 #:property WinAppPackageName=counter 的應用程式會從不同資料夾註冊相同身份。 用 --prune 來清除檔案遺失的註冊。
  • 取消註冊匹配的套件

清理無效登記(--prune):

註冊的存續時間會超過其檔案。 刪除建置輸出、專案樹,或(對於檔案型應用程式)讓 Windows 清理%LOCALAPPDATA%\Temp,套件仍保持註冊狀態:Windows 會保留身份和開始選單的項目,但啟用時卻無聲無息地沒反應。 這些東西會無形地累積起來。

# List dev registrations whose files are gone, then confirm before removing
winapp unregister --prune

# Skip the prompt (required for non-interactive/CI use)
winapp unregister --prune --force

僅考慮開發模式註冊,且每個註冊都會以完整套件名稱移除,因此同名套件仍從現場安裝時不會被修改。 這個提示存在是因為缺少的安裝位置 通常是 已刪除的資料夾,但同時也描述了從斷開網路共享或可移動硬碟註冊的套件——確認前請先查看清單。

範例:

# Unregister from current directory (auto-detects manifest)
winapp unregister

# Unregister a .NET file-based app by its source file
winapp unregister counter.cs

# Unregister with explicit manifest
winapp unregister --manifest ./Package.appxmanifest

# Force unregister even if registered from a different project tree
winapp unregister --force

# Remove every dev registration whose files are gone
winapp unregister --prune

# JSON output for scripting
winapp unregister --json

cert

產生、檢查並安裝開發憑證。

證書生成

產生用於套件簽署的開發憑證。

winapp cert generate [options]

選項:

  • --manifest <Package.appxmanifest>- 從清單Identity/@Publisher中擷取憑證 publisher 。 只需要出版商,所以部分完成的清單仍然有效。 如果清單沒有可用的發佈者,指令會失敗,而不是替換預設值,因此憑證永遠不會無聲地與清單不匹配。
  • --publisher <name>- Publisher 提供證書。 產生憑證時,此選項優先 --manifest於;明確為空值則失敗,無法使用清單發佈者。 接受完整的 X.500 區別名稱(例如 CN=Contoso, O=Contoso Ltd, C=US)或自動包裝為 CN=<name>的純名稱。 組件必須為單值且逗號分隔;多值 RDN(CN=Foo+OU=Bar)與反斜線不被支援,因為 MSIX 清單發佈者無法代表它們。 一個格式不符的區別名稱(例如 CN= 或 CN=A,,O=B)會以非零的出口和錯誤命名問題被拒絕,而不是產生永遠無法匹配清單發佈者的憑證。
  • --output <path> - 輸出憑證檔案路徑(支援絕對與相對路徑)
  • --password <password> - 憑證密碼(預設: password,公開資訊——詳見 JSON 輸出 與 安全性)
  • --valid-days <valid-days> - 證書有效天數(預設:365天)
  • --install - 在產生之後將憑證安裝到本地機器儲存
  • --if-exists <Error|Overwrite|Skip> - 若憑證檔案已存在,則設定行為(預設:錯誤)
  • --export-cer - 匯出檔案 .cer (僅限公鑰)與 .pfx. 用於分發公開證書以進行信託安裝。
  • --json - 將輸出格式化為 JSON 以供程式化消費。 錯誤也會以 JSON ({"error": "..."}) 格式回傳。

JSON 輸出:

{
  "certificatePath": "C:\\app\\devcert.pfx",
  "password": "password",
  "defaultPasswordIsPublic": true,
  "publisher": "Contoso",
  "subjectName": "CN=Contoso",
  "warnings": [
    "Protected with the default password ('password'), which is public. Treat this certificate as development-only: anyone who obtains the .pfx can sign as you. Pass --password to choose your own, and use a CA-issued certificate or Azure Trusted Signing to ship."
  ]
}

publisher 是顯示名稱,也是 subjectName 證書所頒發的完整傑出名稱。 defaultPasswordIsPublic 總是存在。 當它是 true時,它 .pfx 會被一個任何人都能猜到的密碼保護,所以憑證只能簽署只留在你自己電腦上的建置——在腳本把憑證交給其他裝置之前,請先確認。 warnings 與文字內容相同,若無報告內容則省略。 publicCertificatePath 僅出現於 --export-cer。

認證資訊

從 PFX 或 CER 檔案顯示憑證詳細資訊。 這對於在簽署前確認證明是否符合你的清單很有幫助。

winapp cert info <cert-path> [options]

引數:

  • cert-path - 憑證檔案(PFX 或 CER)的路徑

選項:

  • --password <password> - PFX 檔案的密碼,公開 CER 忽略(預設為「password」)
  • --json - 輸出格式化為 JSON

憑證安裝

將憑證安裝到機器憑證儲存庫。

winapp cert install <cert-path> [options]

引數:

  • cert-path - 安裝憑證檔案的路徑

範例:

# Generate certificate for specific publisher
winapp cert generate --publisher "CN=My Company" --output ./mycert.pfx

# Generate certificate and export public key .cer file
winapp cert generate --publisher "CN=My Company" --export-cer

# Generate certificate with JSON output (for scripting)
winapp cert generate --publisher "CN=My Company" --json

# View certificate details
winapp cert info ./mycert.pfx

# View certificate details as JSON
winapp cert info ./mycert.pfx --json

# Install certificate to machine
winapp cert install ./mycert.pfx

標記

用憑證簽署 MSIX 套件和執行檔。

winapp sign <file-path> <cert-path> [options]

引數:

  • file-path - 簽署至 MSIX 套件或執行檔的路徑
  • cert-path - 簽署憑證路徑(.pfx)

選項:

  • --password <password> - 憑證密碼(預設:「password」)
  • --timestamp <url> - RFC 3161 時間戳伺服器網址

範例:

# Sign MSIX package
winapp sign MyApp.msix ./mycert.pfx

# Sign executable with a non-default certificate password
winapp sign ./bin/MyApp.exe ./mycert.pfx --password mypassword

方位符號

使用 Azure 信任簽署 — 一個雲端管理的簽章身份——來對檔案(exe、MSIX 或 MSIX bundle)進行程式碼簽章,因此沒有任何私鑰(PFX)會存在於本地機器上。

winapp az-sign <file-path> [options]

引數:

  • file-path - 簽署檔案的路徑(exe、msix 或 msixbundle)

選項:

  • --subscription, - -s 使用 Azure 訂閱 ID。 如果沒有提供且有多個訂閱,系統會提示你
  • --resource-group, - -r 資源群組以縮小簽署帳戶範圍
  • --account - 簽署帳號名稱。 必須搭配使用 --resource-group
  • --profile, - -p 憑證設定檔名稱。 必須搭配使用 --account
  • --metadata-file, - -m 通往現有 metadata.json的路徑。 跳過資源發現和帳號/個人檔案選擇提示,直接簽署。 非互動式的 Azure 憑證應該已經存在;CLI 可以退回到互動式租戶提示或 az login,但 npm 程式化 API 始終是非互動式,且會失敗而非提示

驗證:

az-sign使用 Azure 標準的憑證鏈(DefaultAzureCredential)。 對於 CI/CD,請設定 AZURE_TENANT_ID、 AZURE_CLIENT_ID、 AZURE_CLIENT_SECRET (或使用 GitHub Actions OIDC / 管理身份)。 現有的 Azure CLI 會話(az login包括 azure/login GitHub Action)在任何環境中也會被尊重。 只有當找不到任何憑證 且 會話是互動式時,會自動 az-sign 啟動 az login 。

先決條件:

  • 一個 Azure 代碼簽署帳號和一個憑證設定檔(在 Azure 入口網站驗證後建立),再加上指派給你身份的代碼簽署憑證設定檔簽署者角色。 欲獲得更多指引,請造訪 Azure Artifact Signing 快速入門文件。
  • 安裝了全機 x64 .NET 8(或更新版本)執行環境。 Azure 簽署客戶端函式庫是一個受管理的組件,會在signtool.exe獨立程序中載入;Winapp 自有的執行環境無法滿足這個需求。 如果簽約失敗且執行時載入錯誤,請從 安裝 https://dotnet.microsoft.com/download 。
  • Microsoft Visual C++ Redistributable(x64)。 Azure 簽署用戶端函式庫依賴 VC++ 執行環境,且因為 WinApp 下載的是原始的 NuGet 套件,而非官方的客戶端工具安裝程式,因此此依賴不會自動安裝。 一台乾淨的機器即使有 .NET 和 SignTool,也可能發生載入失敗。 如果簽署失敗,安裝最新的 x64 redistributable, https://aka.ms/vs/17/release/vc_redist.x64.exe 並出現 0xc000007b「應用程式無法正確啟動」或 dlib 的 missing-dll 錯誤。

最低權限CI: 自動發現(列出訂閱、資源群組、帳號和個人檔案)需要在父範圍有讀取權限。 為避免 每次 集合列示呼叫,先傳遞 --subscription、 --resource-group、 --account、 --profile三個 : az-sign 然後以直接資源讀取(對每個命名資源執行 GET)驗證帳號與設定檔,而非列舉父集合,因此只對該帳戶與設定檔設限的主體即可。 省略任何一項會重新觸發登錄通知——例如,省略 --subscription 這些會列出 az-sign 你的身份可存取的訂閱——而範圍較窄的委託人可能無法這麼做。 僅針對單一憑證設定檔的主體,可以透過傳遞預先產生 --metadata-file 的憑證(直接指定帳戶端點與設定檔)來完全跳過驗證。

範例:

# Interactive — discover/select subscription, account, and profile
winapp az-sign ./app.msix

# Fully specified — no prompting (ideal for CI/CD)
winapp az-sign ./app.msix --subscription <sub-id> --resource-group <rg> --account <account> --profile <profile>

# Reuse an existing metadata.json (skips resource discovery and selection; authentication may still prompt)
winapp az-sign ./app.msix --metadata-file ./metadata.json

建立外部目錄

產生 CodeIntegrityExternal.cat 一個目錄檔案,包含指定目錄中可執行檔雜湊值。 此目錄與 MSIX 稀疏套件清單(AllowExternalContent)中的 TrustedLaunch 旗標一起使用,以允許執行套件本身未包含的外部檔案。

這類似 signtool.exe 於簽署 MSIX 套件時的建立 AppxMetadata\CodeIntegrity.cat 方式,但會產生一個外部目錄,用於稀 疏/外部位置封包。

winapp create-external-catalog <input-folder> [options]

引數:

  • input-folder - 一個或多個包含可執行檔案的目錄以進行處理。 用分號分隔多個目錄(例如, "dir1;dir2")

選項:

  • --recursive, -r - 包含子目錄的檔案
  • --use-page-hashes - 在產生目錄時包含頁面雜湊值(產生更大的目錄,並以每頁雜湊資料計算)
  • --compute-flat-hashes - 在產生目錄時包含扁平檔案雜湊值
  • --if-exists <Error|Overwrite|Skip> - 輸出檔已存在時的行為(預設: Error)
  • --output, - -o 輸出目錄檔案路徑。 若未指定,則 CodeIntegrityExternal.cat 會在目前目錄中建立。 若指定目錄,則會附加預設檔名。

它的用途:

  • 掃描指定的可執行檔案目錄(帶有程式碼區段的 PE 二進位檔)
  • 產生目錄定義檔案(CDF),包含所有已找到執行檔的雜湊值
  • 使用 Windows CryptoCAT API 來產生 .cat 目錄檔案
  • 非可執行檔案(例如 .txt, .dll 無程式碼區段)會自動跳過

範例:

# Generate catalog for all executables in a directory
winapp create-external-catalog ./bin

# Include files in subdirectories
winapp create-external-catalog ./bin --recursive

# Specify a custom output path
winapp create-external-catalog ./bin --output ./dist/CodeIntegrityExternal.cat

# Overwrite existing catalog
winapp create-external-catalog ./bin --if-exists Overwrite

# Skip generation if catalog already exists
winapp create-external-catalog ./bin --if-exists Skip

# Include page hashes (for stricter code integrity validation)
winapp create-external-catalog ./bin --use-page-hashes

# Process multiple directories
winapp create-external-catalog "./bin;./lib" --recursive

# Combine multiple options
winapp create-external-catalog ./bin --recursive --use-page-hashes --compute-flat-hashes --output ./dist/CodeIntegrityExternal.cat --if-exists Overwrite

使用時機:

在建立使用 TrustedLaunch 驗證外部執行檔的稀疏 MSIX 套件時,請使用此指令。 典型的工作流程是:

  1. winapp manifest generate --template sparse — 建立一個稀疏清單 AllowExternalContent
  2. winapp create-external-catalog ./bin — 為您的應用程式執行檔產生程式碼完整性目錄
  3. winapp pack — 將清單、資產與目錄打包成 MSIX

工具

直接使用 Windows SDK 工具。 使用Microsoft.Windows中可用的工具。SDK。BuildTools

winapp tool <tool-name> [tool-arguments]

可用工具:

範例:

# Use signtool to verify signature
winapp tool signtool verify /pa MyApp.msix

簽名驗證

建置工具是從 NuGet 下載後執行的,因此 Winapp 會在執行前立即檢查每個工具是否有有效的 Microsoft Authenticode 簽章。 憑證必須標明簽署機構為 Microsoft Corporation。 這適用於所有向 SDK 工具輸出的指令,包括 tool、 、 package和 sign。 未通過檢查的工具不會執行:

'mt.exe' is not validly signed by Microsoft, so it was not run (C:\...\mt.exe).

這裡失敗表示磁碟上的檔案不是 Microsoft 發布的——通常是損壞或部分下載。 從 NuGet 快取中刪除套件,然後重新執行指令,讓 Winapp 重新下載。

WinApp 會讓工具持續開啟,直到它執行為止,所以它檢查的檔案就是 Windows 載入的檔案。 如果無法固定工具,也不會執行:

'mt.exe' could not be held open for verification, so it was not run (C:\...\mt.exe).

關閉正在使用該檔案的檔案——通常是防毒掃描或開啟編輯器——然後再執行該指令。 如果工具已經消失而非正在使用,請從 NuGet 快取中刪除該套件,讓 winapp 重新下載。


儲存

執行 Microsoft Store 開發者 CLI 指令。 如果尚未下載,此指令將下載Microsoft Store開發者CLI。 了解更多關於 Microsoft Store 開發者 CLI。

winapp store [args...]

引數:

  • args... – 直接提交給 msstore CLI的論點。 請參閱 MSStore CLI 文件 以了解可用的指令與選項。

它的用途:

  • 確保Microsoft Store開發者CLI(msstore)已下載並可存取於你的系統。
  • 將所有參數轉發至 msstore CLI。
  • 直接在終端機執行顯示輸出的指令。

範例:

# List all apps in your Microsoft Partner Center account
winapp store app list

# Publish a package to the Microsoft Store
winapp store publish ./myapp.msix --appId <your-app-id>

get-winapp-path(取得 Windows 應用程式路徑)

取得已安裝的 Windows SDK 元件的路徑。

winapp get-winapp-path [options]

回報內容:

  • 工作 .winapp 區目錄的路徑
  • 套件安裝目錄
  • 產生的標頭位置

目標

執行指令、複製檔案、檢查狀態,或擷取整個訪客桌面。

每個動詞的第一個論元是 take sandbox 。 除了 snapshot,這些指令可以準備或啟動沙盒。 請參閱 Windows 沙盒執行,了解前置條件、權限、生命週期與復原。

Target 執行官

以訪客使用者身份執行指令。

winapp target exec <target> [--cwd <path>] [--json] -- <executable> [arguments...]
winapp target exec sandbox -- dotnet --info

爭吵後 -- 會保持界限。 標準串流與訪客程序的出口碼會被轉發;這不是完整的終端機。 --json 在 stderr 上格式化 winapp 失敗,但不更改子指令的 stdout。 利用結構化 error.code 工具區分目標失敗與應用程式自身的退出狀態。

一個明確 WINAPP_UI_WORKFLOW_ID 的指令也會將來賓 UI 呼叫分組;詳見 沙盒 UI 協調。

目標推與目標拉

將檔案或目錄複製到動詞指定的方向。

winapp target push <target> <host-source> <target-destination> [--json]
winapp target pull <target> <target-source> <host-destination> [--json]
winapp target push sandbox .\setup.ps1 Setup\setup.ps1
winapp target pull sandbox Results .\results

目標路徑是相對於目標所管理的工作區域;絕對、根基及UNC目標路徑皆被拒絕。 檔案目的地包含其檔名。 請參閱 執行指令與複製檔案 ,了解目錄佈局、連結處理及執行複製腳本。

目標快照

報告準備狀況、部署及訪客視窗,無需啟動沙盒。

winapp target snapshot <target> [--json]
winapp target snapshot sandbox

它不會重新連結客戶或修復代理人。 沒有任何運行沙盒是成功的結果,而非錯誤。 請參閱「 檢查沙盒 」以解讀準備狀態與流程識別。

目標截圖

以原生像素大小擷取訪客桌面,作為主機 PNG,無需應用程式選擇器或主機視窗邊框。 --json 遊客報告,座標來源。

winapp target screenshot <target> [-o <host-path>] [--json]
winapp target screenshot sandbox -o .\sandbox.png

ui screenshot --on sandbox -a <app>用應用程式視窗代替。 請參閱 截圖與錄音 ,了解客戶需求、焦點限制及輸出處理。

目標紀錄

將訪客桌面錄製成 H.264 MP4。 主機影片和影格檔案會在錄製結束後送達;JSON 和框架清單描述任何縮放或填充。

winapp target record <target> [-o <host-path>] [--duration-sec <n>] [--fps <n>] [--max-edge <px>] [--frames] [--overwrite] [--json]
winapp target record sandbox -o .\sandbox.mp4 --duration-sec 20 --fps 15

使用持續時間、框架、覆寫和結果選項, ui record但擷取的是桌面,而非單一應用程式。 偏好正值 --duration-sec 用於無人值守的 CLI;npm 助手需要 durationSec。 參見 沙盒擷取 部分證據及捕捉準備失敗。


尋找介面

代理人優先。 find-ui 主要為 AI 編碼代理設計——它讓代理能從出貨圖庫中實際編譯 WinUI 標記,而非自行創造,並 --json 使每個結果(以及每一次失敗)都能被機器讀取。 手打字也一樣好用。

搜尋 WinUI 控制項和範例,尋找可運作的程式碼範例。 僅限 WinUI 使用:語料庫是 WinUI 3 圖庫和 Windows 社群工具包(加上一些精選的核心範本)——不涵蓋 WPF、WinForms 或其他 UI 框架。 第三個來源 microsoft-ui-reactor ReactorGallery 是 自願加入的:它不包含在正常搜尋中,只有在你通過 --source reactor 時才會搜尋(它的 C# 聲明式範例不會貼到標準的 XAML 應用程式中,所以只有在建立 Reactor/MVU 專案時才會使用)。

winapp find-ui "<query>" [options]

Gallery、Toolkit 和 Reactor 語料庫都 存放在 CLI 內,因此 find-ui 無需網路存取即可運作——包括首次在代理沙盒中執行或在封鎖 raw.githubusercontent.com的企業代理後。 當 GitHub 可存取時,CLI 會從 GitHub 重新整理並依每個使用者快取結果;<global .winapp>/cache/find-ui內建語料庫只是一個底線,從來不是上限。 快取資料最多每 24 小時更新一次,或按需更新一次。--refresh

每次建立穩定版時,內建語料庫都會從 GitHub 重新取得,若刷新失敗,則會停止版本建置,而非悄悄地傳送舊資料——Baker 抓取的是相同的程式碼路徑--refresh,因此失敗代表即時更新也壞掉,值得在發佈前調查。 釋放仍可對先前提交的語料庫進行切割,但僅限於明確覆蓋。 當結果從 Gallery/Toolkit/Reactor 的內建副本提供時, find-ui stderr 會顯示,輸出 --json 則 "corpus": "embedded" 攜帶(其他值: "network" 新取用、 "cache" 本地快取)。 僅核心的請求—— --source core或全 --id 核心模式的集合——也會回報 "embedded" ,因為策劃的核心模式會被編譯到CLI中,且從未被取用;它不會列印過時通知,因為 --refresh 無法更改它們。 corpus當結果送達時,欄位會被報告;只有當完全無法載入語料時,欄位才會被報告。

選項:

  • --id <id> - 擷取程式碼(Gallery/Toolkit 回傳 XAML 和/或 C#;反應爐僅支援 C#),並附上先前搜尋時提供的一個或多個情境 ID 的前置註解(例如 gallery-tabview-1)。 可重複。 ID 不區分大小寫 —— GALLERY-TABVIEW-1 解析與 gallery-tabview-1相同。
  • --list - 列出所有可發現的控制/樣本 ID,而非搜尋(Gallery + Toolkit + core;選擇加入的反應器來源不包含)。
  • --source <gallery|toolkit|reactor|core> - 將搜尋結果限制於單一來源。 (僅搜尋 — 不適用於 --list/--id。) 反應爐是選擇加入 的——它不包含在正常搜尋中,因此 --source reactor 是唯一的搜尋方式。
  • --max <N> - 最多可回傳的配對控制數量(預設:3)。 僅適用於搜尋;忽略於 --list/--id。
  • --refresh- 繞過本地快取,從 GitHub 重新取得 WinUI 語料庫。
  • --json - Emit 結構化 JSON(代理友善)。 對於搜尋,每個匹配攜帶 、 、 、 ,以及一個scenarios陣列,該陣列的條目包含每個情境id與header;對於 --id,則為完整程式碼。 descriptionscorecontrolsource 在 --json每次 失敗中——包括參數/解析器錯誤如非整 --max 數——都會以平面物件形式在標準輸出中輸出 {"error": "..."} ,並帶有非零的退出碼,因此輸出仍可機器讀取。

工作流程:簡潔搜尋正確的控制項及其情境 ID,然後取得完整程式碼以取得最佳匹配。--id

範例:

# Find a control by intent (compact results with scenario ids)
winapp find-ui "tabbed layout"

# Restrict to the Windows Community Toolkit
winapp find-ui "settings card" --source toolkit

# Restrict to Reactor (opt-in; C#-only declarative WinUI — Reactor projects only)
winapp find-ui "flex layout" --source reactor

# Fetch the full XAML + C# for a specific scenario
winapp find-ui --id gallery-tabview-1

# Agent-friendly structured output
winapp find-ui "color picker" --json

# Browse everything, or force a corpus refresh
winapp find-ui --list
winapp find-ui "navigation view" --refresh

相關報導:find-ui 搜尋 WinUI 範例;可搜尋 find-api 專案參考的 API 表面 (型別、成員、枚舉),以及 winapp ui search 搜尋 執行中的應用程式的 UI 樹。


find-API

代理人優先。 find-api 主要為 AI 編碼代理而建——它將生成程式碼建立在專案實際參考的 API 表面,而非模型記憶,並且 --json 在缺少符號上加上非零的退出碼,讓代理能對答案進行編碼門。 手打字也一樣好用。

搜尋並檢查專案可用的 Windows/WinRT API 表面(型別、成員、列舉、命名空間),這些資料是從其參考的.winmd/.dll元資料解析而來。 裸表單搜尋;副動詞會鑽入特定類型、命名空間或指標本身。

winapp find-api "<query>" [options]
winapp find-api [command] [options]

索引是在首次使用時從專案還原的 NuGet/SDK 套件(透過 project.assets.json)建立,並在還原時自動刷新。 它位於全域 .winapp 快取(cache/find-api/)下,並跨專案共享。 先還原專案(winapp restore 或 dotnet restore)。

每個配對都會在其命名空間下列出,附帶出貨套件及一行摘要,因此結果可在無需第二次 members 呼叫的情況下使用:

[40] Microsoft.UI.Xaml.Media
    Class Microsoft.UI.Xaml.Media.AcrylicBrush  [Microsoft.WindowsAppSDK.WinUI 1.8.260224000]
        Paints an area with a semi-transparent material that uses multiple effects including blur and a noise texture.

還要列印 --verbose 每個命名空間背後的磁碟快取檔案,這在診斷過時或意外索引時非常有用。

完全不查詢地運行 winapp find-api 會列印簡短的使用摘要然後退出 0 ——這是請求幫助,而非搜尋結果。

範圍。 每個答案都來自一個示波器,在文字輸出中以scope--json註解形式呈現:

  • project - 目前目錄中的專案(或 --project / --project-dir)。 涵蓋 Windows SDK、Windows 應用程式 SDK 以及專案自有的 NuGet 套件。 Windows 應用程式 SDK 的元資料是專案所參考的版本:如果機器安裝了較新的 Windows 應用程式 Runtime,會find-api警告並刪除該資料,而非確認專案無法編譯的類型。
  • sdk- 全機的 Windows SDK + Windows 應用程式 SDK 元資料,當目前目錄中沒有專案且無解決方案時會自動使用。 這使得 find-api 在任何專案尚未存在之前,就能探索 API,且不需要網路存取。 它刻意 不 包含第三方 NuGet 套件,因此(例如)社群工具包中的類型不會在此範圍內找到。

來自沒有專案也沒有解決方案的目錄查詢 ,總是 由 sdk 範圍回應——不會由被索引在共享快取中的專案回應——因此結果永遠不會依賴於無關的全域狀態。 Pass --project sdk 則可直接在專案內明確選取 SDK 範圍,並在winapp find-api refresh --project sdk安裝新 Windows SDK 後重建。

解決方案目錄。 從一個資料夾 .sln/.slnx 裡,旁邊沒有專案檔案,解決方案建置的專案會回答問題,而不是範圍 sdk ——它們會按需被索引,所以 NuGet 套件會被包含在內。 當解決方案建立多個索引專案時,查詢會列出它們並請求, --project <name> 而不是選擇一個。

指令:

  • (裸露)find-api "<query>" ["<query>"...] - 搜尋類型與成員名稱,回退至其文件摘要,依命名空間分組
  • members <type> [<type>...] [--filter <text>] - 列出型別的屬性、事件與方法(宣告帶有簽名的成員,透過宣告型別摘要的繼承成員)
  • check-property <type> <property> [<property>...] - 驗證屬性存在於型態上(若缺少任何屬性,則非零退出)。 唯 讀 屬性會用 ⚠️ 和「只讀,無法指派」來報告,而不是純 ✅,所以像 這樣的 ActualWidth 屬性不會被誤認為可以設定的東西。 屬性名稱是 大小寫區分的,因為 C# 和 XAML 是: check-property Button background 退出非零,並提供 Background 近似匹配,而不是報告你無法實際寫出的名稱。
  • enums <type> [<type>...] [--filter <text>] - 列出列舉的值(當型別不是列舉時,退出非零)
  • packages - 列出索引中的中繼資料套件,並依套件類型/成員數量
  • stats - 顯示彙總索引統計(套件、命名空間、類型、成員、 .winmd 檔案)
  • refresh [--scan] - 重建專案索引(--scan 索引該目錄下的每個專案)。 若 --project <name>名稱不符合單一索引專案,則無法索引當前目錄而失敗。

批次處理、searchmembers、 enums,並在check-property一次調用中接受多個主體。 對 AI 代理來說,這是最大的成本槓桿:查詢的邊際成本主要由往返成本(每次通話重傳整個對話)主導,而非有效載荷大小,因此一通電話回答十個問題遠低於十通電話。

  • 單一主體在文字與 --json中,完全返回其一直以來的有效載荷形狀。
  • 兩個或以上 主體返回一個信封—— { "count": N, "results": [ ... ] } 在 中 --json,每個元素為正常的單主體有效載荷; check-property 相 missingCount加 。 文字輸出會依序將每個主體呈現在同一範圍標頭下。
  • check-property 將 屬性批次處理在一個類型上:第一個參數是該類型,之後的每個參數都是屬性。 在批次模式下,存在的屬性只印出一 ✅ 行;只有沒有的屬性才會印出完整的差點失誤細節。
  • 只有當所有主題都解決並被找到時,批次才會退出0——所以批次仍然是安全的,可以對代碼生成進行門檻。

搜尋排名。 完全匹配型別名稱的查詢會排在部分匹配之前,當一個短名稱被多個命名空間共享時,只有精確名稱的碰撞會被列為歧義——像這樣的 NavigationView 查詢報告的是定義該特定型別的少數命名空間,而非包含相同名稱符號的每個命名空間。 模糊性清單會 --max遵守,正常結果仍印在下面。

輸入名稱.members, check-property,並 enums 接受短名稱()NavigationView或完全限定名稱(Microsoft.UI.Xaml.Controls.NavigationView)。 當一個短名稱被現代Microsoft.*型別與其舊有 Windows.* UWP 雙生型共享時,該Microsoft.*型別會回應——也就是 Windows 應用程式 SDK 應用程式所使用的投影值——並且總是顯示已解析的完全限定名稱。 其他碰撞則非零,並列出候選結果,而非猜測。

方法簽名。 簽名的列印方式與你撰寫呼叫相同:你呼叫的方法是在型別上呼叫,而非實例,會用 static,並以它實際需要的關鍵字 — out、 in、 或 ref顯示一個參考參數。 所以 TryGetValue 讀 Boolean TryGetValue(String key, out String value)起來是按原文編譯的。

選項:

  • --max <n> - 最大命名空間群組搜尋結果數量(預設 5;僅限搜尋)。 同時也會限制歧義清單,讓一個短查詢在多個命名空間中碰撞時仍可閱讀。
  • --filter <text>- 縮小列表範圍,membersenums且:成員/值名稱上大小寫不區分的子字串匹配。 最適合用在有數百名成員的類型上。 大多數枚舉都夠小,可以直接傾倒(甚至 SymbolWinUI 最大的 197 個值),所以過濾通常成本比省下來還多,尤其當你考慮第二次猜測時。 千萬不要用不同的過濾文字重複執行同一個指令——只做一次備份再讀。
  • --all - 在 上 members,列出完整曲面:繼承成員的完整簽名,以及依賴性質識別靜態與每個成員描述,未篩選的列表會省略這些(詳見下方 列表 大小)。 --verbose暗示了它;當你想要--json時也使用--all,且無法與 --verbose合併。
  • --scan - 遞迴式發現並索引目錄下的所有專案(refresh 僅限)
  • --project <name>- Project 查詢(名稱相符.csproj/.vcxproj),或sdk查詢全機 Windows SDK 範圍
  • --project-dir <path>- Project 目錄以查詢(預設為目前目錄)。 不存在的路徑是錯誤——它從未從望遠鏡中被無聲回應 sdk 。
  • --json - 在 stdout 上發出機器可讀的有效載荷(每個動詞都支援)。 查詢有效載荷會識別透過scope(project或sdkprojectName)、、及projectDir(SDK範圍內缺失)回應的索引——專案名稱在目錄間並非唯一,可靠projectDir身份亦然。 在 --json每次 失敗中——包括參數/解析器錯誤如非整 --max 數——都會以平面物件形式在標準輸出中輸出 {"error": "..."} ,並帶有非零的退出碼,因此輸出仍可機器讀取。

範例:

# Search
winapp find-api "acrylic brush"
winapp find-api NavigationView --max 10

# Inspect and validate
winapp find-api members Microsoft.UI.Xaml.Controls.NavigationView
winapp find-api check-property Button Background
winapp find-api enums Symbol

# Batch — one call instead of one per subject
winapp find-api check-property InfoBar Severity IsOpen Message Title
winapp find-api members InfoBar TeachingTip ContentDialog
winapp find-api enums InfoBarSeverity Visibility
winapp find-api "acrylic brush" "teaching tip" --max 5

# Narrow a large type instead of dumping it and grepping
winapp find-api members Button --filter background

# Full member surface: inherited signatures, dependency-property statics, descriptions
winapp find-api members Button --all

# Manage the index
winapp find-api refresh

# Explore the Windows SDK with no project at all (e.g. before scaffolding an app)
winapp find-api "acrylic brush"          # from an empty directory -> scope: sdk
winapp find-api members Button --project sdk

當 --filter 應用時,輸出仍會回報未過濾的總數(totalValues或totalEvents//totalPropertiestotalMethods ),--json因此狹窄的視圖絕不會被誤認為是小型 API。 即使什麼都不匹配,過濾器仍然會 0 明確地說——那是「沒有任何匹配你的過濾器」,而不是「沒有這種類型」。

刊登尺寸。 未篩選 members 的列表是唯一昂貴的形狀—— members Button 涵蓋 288 個成員,其中 280 個是從 6 種基礎類型繼承而來。 未過濾的呼叫是一個 方向查詢 (「這種類型是什麼?大致上它能做什麼?」),因此它回答了這個問題,並省略了未被寫入的部分:

  • 繼承成員簽名 — 繼承成員依宣告類型分組, 僅以姓名列出,因此即使沒有 280 個完整簽名,繼承曲面的形狀仍可見。
  • 依賴屬性識別靜態 (BackgroundProperty) — 典型 WinUI 控制項屬性的 28%。 它們存在是為了傳遞給 GetValue/SetValue,而非被指派。
  • 每位成員的描述 ——XML 文件的散文,約佔有效載荷的 16%。
  • 由其周圍--json環境所蘊含的場: kind (由包含/eventspropertiesmethods/陣列 returnType 隱含)、(的signature首位標記),以及inherited當為假時(由 隱含)。declaringType

省略的部分總是會被報告(hiddenDependencyProperties, descriptionsOmitted, , 以及 a hint--json;文中有「省略:」行),總數仍描述整個類型。 --filter --all兩者都看到完整的表面,包含完整的簽章和描述,因此members Button --filter BackgroundProperty仍能找到識別碼並members Button --filter Click回傳Click繼承的簽章。 以 為 測量samples/winui-app,該值從 members Button --json 91,954 到 10,567 個字元(−88.5%)不等,且位--filter--all元組相同。

查詢如何被匹配。 winapp find-api "language model" LanguageModel高於那些詞彙散落於命名空間與成員的匹配,包括在該類型被索引時,該項目外的匹配。 搜尋是詞彙性的,而非語意性的:它匹配的是整字識別詞,而非任何字母序列,因此 llm 是 IImageLLMAdapterSession ,但不是 ScrollMode。 當查詢不匹配任何名稱時,會嘗試以類型與成員的書面摘要,這也是找出 "random-access stream"IRandomAccessStream的結果。 描述排名低於每個名稱匹配,且只有套件實際出貨的摘要可搜尋——沒有 XML 文件的套件不會提供描述文字。

沒有 MSBuild 專案檔案的專案。 Electron 應用程式(或其他由 winapp.yaml驅動的非 .NET 應用程式)沒有,.csproj因此沒有 project.assets.json。 find-api 索引 .winapp/winmds.lock.json that writes 的 , winapp restore 該 Write 記錄相同內容:每個已解析的套件、其版本及 .winmd 所貢獻的檔案。 此類專案以其目錄命名,當鎖檔重寫時,其索引會變得過時。 同時包含 a .csproj 與 a winapp.yaml 的目錄會從 .csproj索引,後者是專案編譯時更精確的描述。

當索引不完整時,否定答案會被限定。 如果套件的元資料無法讀取,「無此類型」和「該套件從未被索引」看起來完全相同——而對前者採取行動,實際上是後者,卻會產生針對你被告知不存在的 API 的程式碼。 因此,每個否定答案,包括回傳零結果的 a search ,都帶有索引為部分且指向 winapp find-api refresh的註記。 正面回答則不受影響。

通用型別名稱。 元資料會用元數後綴()IAsyncOperation`1來儲存通用型別,這不是任何人寫法的方式。 members enums check-property接受所有形式:IAsyncOperation、、IAsyncOperation<StorageFile>,且IAsyncOperation`1所有皆可解析為相同型態。 純名詞能符合任何標準;所定的元數(無論哪種符號)都必須相符,因此 Holder<A, B> 不會解析為單一參數 Holder<T>。

--json 有效載荷省略了診斷功能。 快取檔案路徑僅出現在 --verbose (匹配文字輸出,原本僅為冗長)下,空建議陣列則省略而非序列化為 []。

出口代碼:search 若無命中、 check-property 缺少屬性及 enums 非枚舉型態,則皆非零出口——閘碼產生與配置間檢查。 若 有主 體失敗,批次呼叫會從非零狀態退出。 唯讀屬性 並非 失敗——它存在,因此 check-property 退出 0 並在輸出writable: false ( 中 --json)標記。 屬性 init 的回報 writable: false 原因相同:它可以在物件初始化器中設定,且其簽名為 { get; init; },但之後指派該屬性不會產生編譯。

相關報導:find-api 回答「這個 API 存在嗎?它的成員有哪些?」;用 find-ui 來尋找一個可運作的 WinUI 控制項範例。


節點產生綁定

(僅提供 NPM 套件)為 Windows 應用程式 SDK API 產生 JS 綁定。 綁定由 中的"winapp": { "jsBindings": {...} }命名空間宣告package.json並寫入.winapp/bindings/。

npx winapp node generate-bindings [options]

選項:

  • --verbose, -v - 啟用每個檔案的冗長碼生成輸出
  • --quiet, -q - 抑制進度與資訊輸出

它的用途:

  • 讀取 winapp.jsBindings 區塊 和 package.jsonwinmds.lock.json 由最後一個 winapp restore寫入的區塊,然後輸出打 .js + .d.ts 型綁定為 .winapp/bindings/
  • 它不會被修改package.json——它是被動再生器。 在啟用 JS 綁定時,新增 winapp.jsBindings 區塊與 @microsoft/dynwinrt 執行時相依性; winapp init 若缺少該區塊,此指令會迅速失敗
  • 如果缺少依賴,會警告(但不會寫入) @microsoft/dynwinrt ——執行 npm install 後 init 已經新增了

備註

綁定僅 為 npm — 需要透過 npx winapp ( @microsoft/winappcli npm 套件)調用;獨立的 Winget CLI 不會顯示這些綁定。 在使用此指令重新生成綁定前,請互動式執行 winapp init 並選擇加入,或使用 winapp init . --use-defaults --add-js-bindings。 如果你編輯winapp.yaml,執行npx winapp restore以刷新 Windows 相依關係再重新建立。

範例:

# Regenerate JS bindings in the current project
npx winapp node generate-bindings

# Regenerate after editing winapp.jsBindings, with verbose output
npx winapp node generate-bindings --verbose

請參閱 JS 綁定指南 ,了解端對端工作流程與 winapp.jsBindings 設定選項。


節點創建外掛

(僅限 NPM 套件提供) 透過 SDK 與 Windows 應用程式 SDK 整合產生原生 C++ 或 C# 外掛範本Windows。

npx winapp node create-addon [options]

選項:

  • --name <name> - 附加元件名稱(預設:「nativeWindowsAddon」)
  • --template - 選擇外掛類型。 選項為 cs 或 cpp (預設: cpp)
  • --verbose - 啟用冗長輸出

它的用途:

  • 建立帶有範本檔案的附加目錄
  • 產生 binding.gyp 和 addon.cc,並附有 SDK 範例Windows
  • 安裝需要npm依賴(nan, node-addon-api, node-gyp)
  • 新增建置腳本指令到 package.json

範例:

# Generate addon with default name
npx winapp node create-addon

# Generate custom named addon
npx winapp node create-addon --name myWindowsAddon

節點添加electorn調試標識

(僅提供 NPM 套件) 透過使用稀疏封裝,將應用程式身份加入 Electron 的開發流程。 需要 Package.appxmanifest(如果沒有就建立一個winapp initwinapp manifest generate)。

這很重要

Electron 應用程式封裝稀疏時已知存在問題,會導致應用程式啟動時當機或無法渲染網頁內容。 這個問題在 Windows 上已經修正,但還沒擴散到外部 Windows 裝置。 如果你在呼叫 add-electron-debug-identity後遇到這個問題,可以在 Electron 應用程式中用旗標停用沙箱 功能,方便除錯 --no-sandbox 。 此問題不影響完整的 MSIX 封裝。

要解除 Electron 偵錯身份,請使用 winapp node clear-electron-debug-identity。

npx winapp node add-electron-debug-identity [options]

選項:

Option 說明
--manifest <path> 自訂 Package.appxmanifest 路徑(預設:目前目錄中的 Package.appxmanifest)
--no-install 請勿安裝或修改相依性;僅設定 Electron 除錯身份
--keep-identity 保持 manifest 的原樣身份,但不要在套件名稱和應用程式 ID 上附加 .debug
--verbose 啟用冗長輸出

它的用途:

  • 暫存器除錯程序 electron.exe 身份
  • 使 Electron 開發中能測試需要身份的 API
  • 使用現有的 Package.appxmanifest 來設定身份

範例:

# Add identity to Electron development process
npx winapp node add-electron-debug-identity

# Use a custom manifest file
npx winapp node add-electron-debug-identity --manifest ./custom/Package.appxmanifest

節點 清除 Electron 偵錯身份情報

(僅提供 NPM 套件) 透過從備份還原原始 electron.exe,從 Electron 除錯程序中移除套件身份。

npx winapp node clear-electron-debug-identity [options]

選項:

Option 說明
--verbose 啟用冗長輸出

它的用途:

  • 從由electron.exe add-electron-debug-identity
  • 還原後會移除備份檔案
  • 將 Electron 回歸原始狀態,無需封裝身份

範例:

# Remove identity from Electron development process
npx winapp node clear-electron-debug-identity

全域選項

所有指令都支援以下全域選項:

  • --verbose, -v - 啟用冗長輸出以供詳細記錄
  • --quiet, -q - 抑制進度訊息
  • --help, - -h 顯示指令協助

全球快取目錄

Winapp 建立一個目錄來快取檔案,這些檔案可以在多個專案間共享。

預設情況下,Winapp 會建立一個 $UserProfile/.winapp 目錄,作為全域快取目錄。

要使用不同位置,請設定環境 WINAPP_CLI_CACHE_DIRECTORY 變數。

在 指令長中:

REM Set a custom location for winapp's global cache
set WINAPP_CLI_CACHE_DIRECTORY=d:\temp\.winapp

在 PowerShell 和 pwsh中:

# Set a custom location for winapp's global cache
$env:WINAPP_CLI_CACHE_DIRECTORY=d:\temp\.winapp

當你執行像 init 是 or restore的指令時,Winapp 會自動建立這個目錄。

更新檢查

winapp CLI 會定期檢查是否有新版本,並在有更新時顯示一行通知。 這個檢查是在背景執行,且不會增加指令延遲。

更新檢查會在 CI 環境(例如 GitHub Actions、Azure Pipelines 等)中自動停用。

若要手動停用更新檢查,請將環境變數設 WINAPP_CLI_UPDATE_CHECK 為 0。

在 指令長中:

set WINAPP_CLI_UPDATE_CHECK=0

在 PowerShell 和 pwsh中:

$env:WINAPP_CLI_UPDATE_CHECK = "0"

要讓這件事成為永久:

[System.Environment]::SetEnvironmentVariable('WINAPP_CLI_UPDATE_CHECK', '0', 'User')

UI 工作流程識別碼

winapp ui 驅動實體桌面的指令總是以合作方式進行,因此兩個同時執行的工作流程不會搶走彼此的焦點或忽略彼此的選單。 這種仲裁不需要設定,也無法關閉。

可選的是 連續性。 預設情況下,每個指令都是獨立的一次性任務,完成後立即釋放桌面。 為了讓桌面在多個指令間保持一致,請給它們相同的工作流程 ID:

$env:WINAPP_UI_WORKFLOW_ID = [guid]::NewGuid().ToString()

對協作流程(例如錄影和應該捕捉的點擊)使用 相同的 數值,獨立的工作流程則用 不同的 數值。 每個沒有 ID 的指令都是獨立的一次性工作流程,即使從一個 shell 啟動多個指令,因此每個指令啟動新 shell 的主機必須在每個 shell 中注入相同的明確值。 該值是不透明的,從未被視為憑證,且只會以 SHA-256 雜湊值形式持續存在。 請參見使用者介面自動化 →協調並行 UI 工作流程。

ui

使用 使用者介面自動化(UIA)檢查並互動正在執行的 Windows 應用程式介面。

winapp ui [command] [options]

指令:

  • status - 連接應用程式與節目資訊
  • inspect - 檢視元素樹
  • search - 透過選擇器尋找元素
  • get-property - 讀取元素屬性
  • get-text / get-value - 從元素(TextPattern、ValuePattern 或 Name)讀取值/文字
  • screenshot - 以 PNG 格式擷取視窗/元素(多個視窗組成一個標示為 composite PNG;參見 擷取範圍)
  • record- 將視窗/元素區域錄製到 H.264 MP4 影片(Windows Graphics Capture + Media Foundation)
  • invoke - 啟動元素(點擊、切換、展開)
  • click - 透過滑鼠模擬點擊元素(用於不支援 invoke 的控制項)
  • hover - 將滑鼠移至元素以觸發提示、飛出及懸停狀態(預設停留時間:800毫秒)
  • drag - 透過元素選擇器或螢幕 x,y 座標(重新排序、調整大小、滑桿、拖放)將滑鼠從一個點拖到另一個點
  • touch - 在元素中心或螢幕 x,y 座標注入合成觸控手勢(點擊、雙擊、長按、滑動、捏合、拉伸)
  • pen - 注入合成筆/觸控筆輸入 — 點擊與墨筆筆劃,並可設定壓力、傾斜與橡皮擦模式
  • send-keys - 將合成鍵盤輸入(命名鍵、組合鍵、原始 vk=0xNN 或文字文字)傳送到視窗
  • set-value - 設定可編輯元素(文字、數字)的值;為了僅 TextPattern 的豐富編輯控制,則會退回到 LegacyIAccessible put_accValue 。
  • focus - 移動鍵盤焦點
  • scroll-into-view - 捲軸元素可見
  • wait-for - 等待元素狀態
  • list-windows - 列出應用程式的所有視窗
  • get-focused - 報告當前聚焦的元素
  • yield - 釋放當前工作流程的 UI 回合;要求 WINAPP_UI_WORKFLOW_ID

選項:

  • -a, --app <app> - Target 應用程式(名稱、標題或 PID)
  • -w, --window <hwnd> - HWND(穩定版)的目標視窗
  • --on <target> - 執行任何 ui 動詞; sandbox名稱、PID 和視窗代言人都指向訪客。 輸出會傳送給主機。 請參閱 沙盒 UI 自動化 ,了解設定、工作流程協調及客戶需求。

UI 紀錄

將視窗或元素區域錄製到 H.264 MP4。

# Record a window for 10 seconds at 15 fps
winapp ui record -a Calculator --duration-sec 10 --fps 15 -o demo.mp4

# Record until Ctrl+C, downscaled so the longest edge is 1280px
winapp ui record -a "My App" --duration-sec 0 --max-edge 1280 -o capture.mp4

# Record just one element's region
winapp ui record -a "My App" btn-save-1234 -o button.mp4

# Keep an agent-readable timeline alongside the MP4
winapp ui record -a Calculator --frames --duration-sec 10 --fps 10 -o evidence.mp4

紀錄選項:

  • --duration-sec <n> - 以秒計的記錄長度。 0 記錄直到 Ctrl+C(預設 0)。
  • --fps <n> - 每秒擷取幀數(預設 15)。
  • --max-edge <px> - 縮小,使最長邊最多為此像素數(0 = 無下縮尺)。
  • --capture-screen - 從螢幕擷取,包含覆蓋層/彈出視窗(可能捕捉遮蔽視窗)。
  • -o, --output <path> - 輸出 .mp4 路徑(預設為 recording-<timestamp>-<guid>.mp4)。
  • --overwrite - 新錄音結束後替換現有的輸出;現有輸出預設會被拒絕。 先前的框架組合會被保留。 請參見 「錄製輸出恢復」。
  • --frames- 寫入帶有時間戳記的 JPEG,frames.ndjson且manifest.json寫入。<output-name>.frames 支援 1-30 fps 及 --max-edge 64-4096(預設 1280),並有 1 GiB 的幀數上限。

其中 --json,最終結果包含輸出路徑、尺寸、編解碼器、擷取模式、節奏、停止理由、可選 frameArtifacts性 和 警告。

已知限制: 在彈出視窗中錄製 特定元素 ,該彈窗會呈現在自己的頂層視窗(WinUI/XAML flyout、教學提示、工具提示)中,可能會擷取底層的主視窗。 可以錄下整個視窗,或是依照 截圖疊加的流程 來處理彈出靜態畫面。 追蹤於 #646。

完整文件請參見 docs/ui-automation.md。