Shell 完成
为命令、选项和值启用选项卡完成。 有关设置说明,请参阅 Shell 完成指南 。
# 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 安装模式:“stable”(默认值)、“预览”、“实验”或“none”(跳过 SDK 安装) -
--ignore-config,--no-config- 不要将配置文件用于版本管理 -
--no-gitignore- 不更新 .gitignore 文件 -
--use-defaults,--no-prompt- 不提示并使用所有提示的默认值 -
--config-only- 仅处理配置文件操作,跳过包安装 -
--exe <path>- 应用程序可执行文件的路径。 需要--sparse。 为 exe 生成仅限标识的稀疏清单,而不是完整的包/SDK 设置。 -
--sparse- 为现有桌面 exe 生成稀疏标识清单 (appxmanifest.xml)。 跳过 SDK/包安装。 与--exe结合使用。 -
--name <name>- 重写包名称(仅稀疏;默认值:从 exe 推断) -
--publisher <CN>- 重写发布者 CN (仅稀疏;默认值:从 exe 的公司名称推断) -
--output-dir <path>- 用于写入稀疏清单的目录(Assets/仅稀疏;默认值:sparse/当前目录中的文件夹) -
--force- 覆盖目标目录中的现有appxmanifest.xml项(仅稀疏)。 如果没有它,init 将失败,而不是替换现有的清单/资产。 -
--add-js-bindings(仅限 npm) - 添加到winapp.jsBindingspackage.json 并生成 JS/TypeScript 绑定,而不提示(不兼容--setup-sdks none)
功能:
-
winapp.yaml创建配置文件(仅当管理 SDK 包时;跳过时--setup-sdks none) - 下载 Windows SDK 和 Windows 应用 SDK 包
- 生成 C++/WinRT 标头和二进制文件
- 创建 Package.appxmanifest
- 设置生成工具并启用开发人员模式
- 更新 .gitignore 以排除生成的文件
- 将可共享文件存储在全局缓存目录中
- 启用时为Windows 应用 SDK API 生成 JS 绑定(仅限 npm)
自动项目检测:
init在没有目录参数的情况下运行时,它会对当前目录树执行广度优先搜索以查找兼容项目(最多 10 个)。 支持的项目类型:
-
Tauri -
tauri.conf.json在目录下找到一个级别 -
Electron -
package.json具有electron依赖项或 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 - 在非交互式环境中(管道 stdin、CI、重定向输入),
init会自动使用--use-defaults行为并发出警告:Non-interactive environment detected. Using default values. - 如果当前目录是兼容项目,
init请立即继续 - 如果正好在其他地方找到一个项目,系统会提示你确认
- 如果找到多个项目,则可以选择要初始化的项目 — 当前目录始终可用作回退选项
- 如果未找到任何项目,系统会发出警告并询问是否继续
- 如果搜索达到 10 个项目限制,则警告建议提供目录参数
自动.NET项目流:
在目标目录中找到 .csproj 文件时,init 使用简化的 .NET 特定流程:
- 验证并更新与Windows兼容的 TFM 的
TargetFramework(例如,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 依赖项),并且仅生成清单和占位符资产。
- 通过
FileVersionInfo(使用--name--publisher、或交互方式替代)从 exe 推断包名称、发布者、说明和版本 - 将
appxmanifest.xml(替换为 exe 名称Executable)和Assets/文件夹写入sparse/当前目录中的文件夹(或--output-dir) - 用于
--use-defaults/--no-prompt跳过交互式重写提示(CI 友好) -
--exe没有--sparse错误
资产是外部资产。 稀疏
.msix是仅限标识的:生成的Assets/是在运行时从应用的安装目录(外部内容位置)解析的, 而不是 捆绑到其中.msix。 将它们与应用程序一起部署。
后续步骤winapp init --exe <exe> --sparse:生成标识.msix,然后winapp embed-identity <exe>winapp pack <appxmanifest.xml>。 有关完整演练,请参阅 稀疏打包指南 。
示例:
# 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
如果使用(或跳过的 SDK 安装)运行 init--setup-sdks none ,以后需要 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 应用 SDKdotnet new模板创建新的 WinUI 应用。 默认情况下,交互;自动在非交互式环境中使用默认值。
winapp new [options]
选项:
-
-t, --template <short-name>- 模板短名称(例如winui,、winui-navview、winui-mvvmwinui-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# 代码隐藏在标记中定义 UI。
反应器 模板是纯 C#,没有 XAML,使用 MVU (模型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 |
实验的。 空白 Reactor 应用 - 纯 C#,无 XAML |
reactor-mvu |
实验的。 演示 MVU 模式的 Reactor 应用 |
reactor-navview |
实验的。 Reactor NavigationView 初学者应用 |
reactor-tabview |
实验的。 Reactor TabView 初学者应用 |
反应堆模板是实验性的。 它们引用预发行版
Microsoft.UI.Reactor包,其 API 可以在将来的版本中更改或删除。winapp new在交互式选取器中和交互选取器中--list标记它们,"Experimental": true--json并在搭建基架后打印警告。 从不选择它们作为默认模板。 Reactor 还需要 .NET 10 SDK 或更高版本;在较旧的 SDKwinapp new上,它需要的版本失败,而不是搭建无法生成的项目基架。
每个模板的规范短名称都是它的第一个别名列表;也接受任何列出的别名dotnet new(例如winui3wasdk-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 package和使用dotnet restore,因此请将专用源的配置放在项目目录或上级中。
--config-dir报告并忽略该层次结构的外部,而不是以无提示方式选择项目无法还原的版本。 仅针对你信任的目录运行这些命令,同样适用于 dotnet restore。 配置多个源时,请使用 包源映射 将每个包固定到源。
更新
将包更新到其最新版本并更新配置文件。
winapp update [options]
选项:
-
--setup-sdks <stable|preview|experimental|none>- SDK 安装模式:stable(默认)、preview或experimentalnone(跳过 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 捆绑包。 对于 稀疏标识包,请直接传递稀疏appxmanifest.xml文件而不是文件夹(请参阅下面的 稀疏标识包 )。
选项:
-
--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$解析清单中的令牌(请参阅下面的清单占位符) - 确保合理的框架依赖项
- 使用注册信息更新并行清单
- 如果清单目录中缺少任何非映像文件(例如,AppExtension
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 是冲突,并且被拒绝。
项目必须生成为打包的应用(EnableMsixTooling=true 带有一个 Package.appxmanifest);生成为未打包的应用(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清单,没有应用程序二进制文件或资产。 这是 稀疏打包工作流的步骤 2。
# Build a signed identity package from a sparse manifest
winapp pack ./sparse/appxmanifest.xml --cert ./devcert.pfx
- 输出默认为
<PackageName>.identity.msix当前目录中的输出(使用重写 )。--output - 仅当提供 (或
--generate-cert) 时--cert,才会进行签名。 - 如果改为传递一个声明
AllowExternalContent其清单的文件夹,则应用现有文件夹打包行为,但如果winapp pack它查找资产(.ico//.png.jpg)或二进制文件(.exe.dll//.so),则会警告这些资源属于外部位置的稀疏包,而不是位于外部.msix位置。
打包后,在安装程序Add-AppxPackage -Path <msix> -ExternalLocation <install-dir>中运行winapp embed-identity <exe>并注册包。 请参阅 稀疏打包指南。
WinRT 组件发现
打包时,winapp pack自动扫描在或winapp.yaml针对第三方 WinRT 组件(例如 Win2D)中*.csproj定义的 NuGet 包。 它分析 .winmd 文件以提取可激活的类名并查找其实现 DLL。 发现的条目注册如下:
-
依赖于框架的类(默认值):可激活类作为条目添加到
<InProcessServer>Package.appxmanifest -
自包含 类:
--self-contained可激活类嵌入可执行文件中的并行清单(SxS)
打包期间的占位符分辨率:
如果清单包含在 $targetnametoken$ 属性中 Executable :
- 如果
--executable提供(相对于输入文件夹的路径),则占位符将替换为指定的值 - 否则,
winapp pack扫描输入文件夹根.exe文件 - 如果正好找到一个文件,则会自动使用它 - 如果找到零个或多个
.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。
捆绑包的清单解析:
捆绑包中的每个切片都需要清单。 该命令按以下顺序解析清单:
--manifest <path>- 如果指定,则此单个清单用于所有切片。 每个ProcessorArchitecture切片都会自动更新,以匹配检测到的体系结构。每个文件夹清单 - 如果每个输入文件夹包含一个
Package.appxmanifest(或appxmanifest.xml),该文件夹的清单用于其切片。当前目录回退 — 如果某个文件夹没有清单,则命令在当前工作目录中查找
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:当create-debug-identityexe 与应用代码(例如位于何处electron.exenode_modules的 Electron 应用)分开时使用,或专门测试稀疏包行为时使用。 对于大多数可执行文件位于生成输出文件夹中的框架,请改用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
embed-identity
通过将元素嵌入<msix>应用的并排(fusion)清单,将桌面应用程序连接到其稀疏标识包。 这是稀疏打包工作流的步骤 3 — 它告知Windows正在运行的 exe 所属的标识包。
winapp embed-identity <target> [options]
参数:
-
target- 要更新的文件。 按扩展自动检测:-
.exe(EXE 模式) - 使用mt.exe将<msix>元素直接嵌入 exe 的并排清单中。 -
.xml/.manifest(XML 模式) - 插入或替换<msix>外部 SxS 清单文件中的元素(如果不存在)。 之后重新生成应用,以便更新的清单嵌入到二进制文件中。
-
选项:
-
--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 文件。
清单生成
从模板生成 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) 时的行为
模板:
-
packaged- 标准打包的应用清单 -
sparse- 使用稀疏/外部位置打包的应用程序清单
清单占位符
生成的清单使用 $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,清单元数据(版本、说明)和图标将从可执行文件中提取,但生成的清单仍使用$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 add-alias
将执行别名 (uap5:AppExecutionAlias) 添加到 Package.appxmanifest。 这允许通过键入别名从命令行启动打包的应用。
winapp manifest add-alias [options]
选项:
-
--name <alias>- 别名(例如myapp.exe)。 默认值:从Executable清单中的属性推断。 -
--manifest <path>- Package.appxmanifest 的路径(默认值:搜索当前目录) -
--app-id <id>- 将别名添加到的应用程序 ID(默认值:第一个应用程序元素)
功能:
- 读取清单并从属性推断别名
Executable(保留类似$targetnametoken$.exe占位符) -
uap5添加命名空间声明(如果尚不存在) - 在目标 Application 元素中添加一
<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 个缩放变体 - base (无后缀)、
.scale-125、、.scale-150、.scale-200.scale-400
对于应用图标(Square44x44Logo / AppList,44×44 base):
-
14 个板化目标变体 -
.targetsize-{16,20,24,30,32,36,40,48,60,64,72,80,96,256} -
14 个未打板的目标化变体 —
.targetsize-{size}_altform-unplated
此外:
-
app.ico — 用于 shell 集成的多分辨率 ICO 文件(16、24、32、48、256)。 如果在资产目录中找到现有
.ico文件(例如AppIcon.ico从项目模板),则会就地替换它,而不是创建重复文件
使用 --light-image:
-
浅色主题目标化变体 -
.targetsize-{size}_altform-lightunplated(应用图标) -
浅色主题缩放变体 -
.scale-{factor}_altform-colorful_theme-light(磁贴,应用商店徽标)
SVG 支持: SVG 文件作为源图像完全受支持。 它们直接在每个目标大小上呈现为矢量,在所有分辨率上生成像素完美结果。 文件必须通过 viewBox 绝对 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 以三种模式之一运行,从输入中自动选择:
-
文件夹模式 - 输入是生成输出文件夹(包含 a)。
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.)。 仅当具有可运行的应用位于其顶层时.csproj//.sln.slnx,目录才会生成为项目;不会以递归方式进行搜索。
对于大多数框架(.NET、C++、Rust、Flutter、Tauri)来说,这是使用包标识进行调试的首选命令。 与为单个 exe 注册稀疏包不同
create-debug-identity,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 将所需的uap5:ExecutionAlias添加到 AppX 布局中分阶段的清单,因此不需要对签入清单进行更改;应用声明自己的别名 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已加载),则会自动运行额外的存根异常会审传递,以显示原始 HRESULT、其 ErrorContext 链和完整的本机 XAML 调度堆栈;首次使用时下载所需的调试器组件(请参阅 调试,可通过WINAPP_DBGTOOLS_DIR环境变量重写)。 一次只能有一个调试器附加到进程,因此不能同时使用其他调试器(Visual Studio,VS Code)。 如果需要附加其他调试器,请--no-launch改用。 不能与--no-launch.. 不能与--json.. -
--symbols- 从 Microsoft Symbol Server 下载 PDB 符号,以便使用解析的函数名称进行更丰富的本机崩溃分析。 只能与--debug-output配合使用。 如果省略并发生本机崩溃,输出将建议添加此标志。 此标志还改进了 WinUI 3 应用的 WinUI 存根异常会审堆栈。 首先运行下载符号并将其缓存在本地;后续运行使用缓存。 -
--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,不回退到本地执行。 在后续 UI 命令之前使用--detach。 沙盒--debug-output需要打包的应用。 请参阅Windows沙盒执行,了解设置、运行时支持和分离的应用生存期。
应用程序数据持久性:
默认情况下,重新部署时保留winapp run应用程序的数据(LocalState、RoamingStateSettings等)。 如果应用将数据 ApplicationData.Current.LocalFolder 写入包上下文或 Environment.GetFolderPath(SpecialFolder.LocalApplicationData) 包上下文中,该数据会在调用中 winapp run 幸存下来。
需要全新启动时使用 --clean (例如重置损坏的状态或测试首次运行行为)。
功能:
- 查找或生成 Package.appxmanifest
- 使用松散布局包创建和注册调试标识
- 计算应用程序用户模型 ID (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 属性自动检测到打包与解压缩(从不从清单状态):
-
打包 (
WindowsPackageType=MSIX,WinUI 打包默认值)- 生成,然后将生成输出注册为松散布局包,并通过 AUMID 启动(与文件夹模式相同的管道)。 -
解压缩 (
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 布局的情况下使用包标识的应用,请包含或appxmanifest.xml包含在Package.appxmanifest项目的发布输出中。 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- 在生成或本机 AOT 发布之前跳过还原。 (在单文件模式下也受支持)。 -
--aot- 运行项目的配置.NET本机 AOT 发布。 需要有效PublishAot=true。 在文件夹和单文件模式下被拒绝。 -
-p, --property <Name=Value>- MSBuild 属性,转发到生成和属性评估。 对多个属性重复-p;在%3B值中使用或%2C用于文本分号或逗号。 (在单文件模式下也遵循此模式,这是设置TargetFramework的唯一方法。
生成输出和详细程度: 普通项目运行使用 dotnet build,然后评估生成的输出。 实时还原和生成输出流,其中包含经过身份验证的源 URL 的凭据。 使用 --aotwinapp 时,winapp 使用 dotnet publish; --verbose 显示发布命令和解析的路径。 使用下面的详细选项来控制显示的内容:
| Flag | dotnet verbosity | 添加 |
|---|---|---|
| (默认) | minimal |
— |
--verbose |
minimal |
winapp 的生成决策跟踪 |
--quiet |
quiet |
— |
本机 AOT 在到达时发布输出流。 在以下情况下 --json,还原/生成调用和子输出将转到 stderr,以便 stdout 保持纯 JSON。 在以下 --quiet情况下,取消调用,dotnet 的安静还原/生成输出将路由到 stderr,以便 stdout 保持干净。 本机 AOT 发布输出也会转到任一选项下的 stderr。
选项适用性:标识/松散布局选项(--manifest、--no-launch--with-alias--output-appx-directory、--unregister-on-exit、、--clean)--executable仅适用于打包的应用。 对于未打包的应用(没有 MSIX 包),它们被拒绝,并出现明确的错误。 启动/调试选项(--args/--、、--debug-output--detach、--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 和“开始”菜单条目,以及只需标识(应用通知、 ApplicationData设备上的 AI)的 API 即可工作。
Shell 集成(如协议处理程序、文件关联、共享目标和启动任务)需要声明 <Extensions> 的条目,生成的清单不包含该条目。 若要添加清单,请创作自己的清单 , 请参阅下面的 “自带清单 ”。
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 (包标识) |
文件名,清理为 [-.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 的组件或超过 4 个组件) 被拒绝,并出现错误 而不是无提示更改。
Capabilities
应用使用标识运行完全信任,该标识满足仅需要打包应用的 API。 但是,无论声明的功能如何,某些 API 都会受到限制,Windows AI API 是常见情况。 (协议处理程序和文件关联等 Shell 集成是第三种情况:这些需要创作 <Extensions> 的条目,而不是功能,因此请为它们使用 自己的清单 。
#:property WinAppCapabilities=systemAIModels
这就是清单所需的所有 Phi 硅和其他设备型号 API。 通过分隔多个声明它们:
#:property WinAppCapabilities=systemAIModels;internetClient;microphone
winapp 将每个元素和实际需要的 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拒绝注册或接受,同时无提示不授予它。
自带清单
如果需要属性未涵盖的内容(协议处理程序、文件关联、执行别名),请创作清单,并 winapp run 逐字使用清单,而不是生成清单。 按顺序从中选取它:
-
--manifest <path>在命令行上。 -
#:property WinAppManifestPath=<path>在.cs文件中。 - 位于文件旁的
.cs清单,命名<filename>.appxmanifest(例如counter.appxmanifest旁边counter.cs)。
仅自动选取每个文件名。
Package.appxmanifest故意忽略同一文件夹中的一个或appxmanifest.xml同一文件夹中的多个.cs文件可以共享文件夹,采用共享名称会以无提示方式在另一个应用的标识下运行一个应用。 若要对多个文件使用一个清单,请通过 --manifest 或显式 WinAppManifestPath命名它。
否则,生成输出中会生成 a Package.appxmanifest 以及默认映像资产,并在每次运行时刷新。
Options. 每个文件夹模式选项都有效:--no-launch、、、--detach--with-alias--without-alias、 --clean--no-build/--args----unregister-on-exit--json--executable--symbols--debug-output--output-appx-directory-c/--configuration--manifest--no-restore和。-p/--property
Tip
默认情况下,控制台应用会打印到终端。 通过 AUMID 启动的打包应用没有主机,因此仅控制台应用将正常运行,不打印任何内容。 winapp 可避免这种情况:通过执行别名启动具有 OutputType=Exe 的应用,该别名继承此终端的 stdin/stdout/stderr。 你仍会收到包标识,无需请求它:
winapp run counter.cs
传递 --without-alias 以强制 AUMID 激活 — 应用随后在没有控制台的情况下运行,在此处不打印任何内容。 窗口化应用 (WinExe) 显示一个窗口,因此它会保留 AUMID 激活;如果需要此终端中的一个,请传递 --with-alias 。 若要修复文件中的选项,而不是在每个命令行上,请设置一个 .csproj 使用的相同属性:
#:property WinAppRunUseExecutionAlias=false
别名 winapp 声明以 python.cswinapp-…别名,从不python.exe。 如果你创作自己的清单,则声明有 as-is 使用的别名,winapp 不会添加任何内容。
这仅适用于别名。 注册本身以程序包 名称为键,因此运行另一个应用,在不同的发布者下声明相同的 WinAppPackageName 应用会替换第一个注册,而不是坐在它旁边。 如果希望同时注册两个应用,请为每个应用提供其自己的名称。
winapp run 打印已注册的别名,因此无需计算哈希才能找到它。
别名是路径上的命令,只要包保持注册状态,该命令就持续。 如果其他一些包已经拥有该名称,winapp 会这样说。 当它推断出它通过 AUMID 启动的别名时,而不是启动错误的应用;当你要求一个显式的 - 有 --with-alias 或 #:property WinAppRunUseExecutionAlias=true - 它失败, 而不是悄悄地做其他事情。
两个项目模式选项 不适用 ,因为基于文件的应用会自行配置。 它们被拒绝,消息命名为要使用的指令:
| 选项 | 请改用 |
|---|---|
-f/--framework |
#:property TargetFramework=net10.0-windows10.0.22621.0 |
--project |
nothing — .cs 文件 是 项目 |
--arch 并 -r/--runtime 像在项目模式下一样工作。 如果不传递任何一项,则 winapp 生成适用于计算机的体系结构,这是自包含Windows 应用 SDK应用需要的内容,因为它没有 SDK 生成AnyCPU并失败WindowsAppSDKSelfContained requires a supported Windows architecture。 文件中的 A #:property RuntimeIdentifier=win-arm64 受到尊重;显式 --arch/--runtime 重写该文件。
打包和解压缩这两个工作,从与项目模式完全一样有效WindowsPackageType检测到:默认注册松散布局并使用标识启动它,同时#:property WindowsPackageType=None生成应用,安装匹配Windows 应用运行时,并直接启动.exe它。 (打包的应用是通过执行别名或通过 AUMID 激活启动的, 请参阅上面的控制台说明;该选择与它是否打包是分开的。标识选项(--no-launch、、、--with-alias--without-alias--clean、、--unregister-on-exit、--manifest)--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,其中包、注册并启动刚刚生成的应用 dotnet run ,它不会重新生成。 清单处理保持不变:winapp 会像它一winapp run样解析它,因此#:property WinAppManifestPath=…,除了这.cs两者<filename>.appxmanifest都受到尊重(请参阅“自带清单”),目录范围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解压缩路径。
设置为#:property EnableWinAppRunSupport=false完全退出重定向,在WinAppRun*“配置”下描述的属性可调整启动,例如:
#: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不需要清单路径:它以相同的方式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 的可键 WinAppPackageName 关闭 $(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 个字符的名称,结果上限为 50 个字符 1,因此 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
可以在控件 .csproj 行为中设置以下 MSBuild 属性:
| 财产 | 违约 | 说明 |
|---|---|---|
EnableWinAppRunSupport |
true |
启用/禁用运行支持功能 |
WinAppLaunchArgs |
(空) | 在启动时传递给应用的参数 |
WinAppRunUseExecutionAlias |
从应用推断 | 通过执行别名而不是 AUMID 激活启动。 左未设置,winapp 推断它:控制台应用使用别名,以便其输出到达终端,窗口化应用使用 AUMID。 设置 true 或 false 自行决定。 |
WinAppRunNoLaunch |
false |
仅注册标识而不启动 |
WinAppRunDebugOutput |
false |
捕获 OutputDebugString 消息和第一机会异常。 一次只能附加一个调试器(防止 VS/VS Code)。 请 WinAppRunNoLaunch 改为附加其他调试器。 |
WinAppRunDetach |
false |
启动后立即返回,而不是等待应用退出。 打印 PID。 |
WinAppRunUnregisterOnExit |
false |
在应用退出后注销开发包 |
WinAppRunClean |
false |
在重新部署之前删除现有包的应用程序数据(LocalState,设置) |
WinAppRunSymbols |
false |
从Microsoft符号服务器下载符号,以便进行更丰富的本机崩溃分析。 只有一个效果与 WinAppRunDebugOutput. |
WinAppRunExecutable |
(空) | 相对于生成输出文件夹的可执行路径。 当清单包含 $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>
注销
取消注册旁加载的开发包。 仅删除在开发模式下注册的包(例如,通过 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>- 从sandbox此计算机中删除匹配的 winapp 拥有的开发注册。 需要清单,不支持--force。 请参阅 沙盒应用清理。 -
--prune- 删除文件消失的每个开发模式注册。 不能与输入、--manifest、--property、--configuration、--arch、或--runtime--output-appx-directory组合在一起。 -
-p, --property <Name=Value>- 解析.cs基于文件的应用的标识时使用的 MSBuild 属性。 重复。 传递运行所使用的相同标识影响属性(例如-p WinAppPackageName=...),因为命令行属性会替代文件自己的#:property指令。.cs仅适用于输入。 -
-c, --configuration <name>- 生成在解析.cs基于文件的应用的标识时使用的配置。 默认值:Debug。 传递使用的相同配置:一个Directory.Build.props旁可以设置WinAppPackageName或有条件地设置$(Configuration)。WinAppManifestPath.cs.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>- 如果证书文件已存在,请设置行为(默认值:错误) - 与 < a0 /> 一起导出文件(仅限公钥)。 用于单独分发公共证书以用于信任安装。 -
--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 时间戳服务器 URL
示例:
# 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
az-sign
使用Azure 受信任签名(云托管签名标识)对文件(exe、MSIX 或 MSIX 捆绑包)进行代码签名,因此本地计算机上从未有私钥(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_IDAZURE_CLIENT_SECRET (或使用 GitHub Actions OIDC/托管标识)。 任何环境中也遵循现有的Azure CLI会话(az login包括azure/loginGitHub操作)。 仅当找不到凭据 并且 会话是交互式的时,才会 az-sign 为你启动 az login 。
先决条件:
- Azure代码签名帐户和证书配置文件(在标识验证后在Azure门户中创建),以及分配给标识的代码签名证书配置文件签名者角色。 有关更多指导,请访问Azure项目签名快速入门文档。
- 安装了计算机范围的 x64 .NET 8(或更高版本)运行时。 Azure签名客户端库是在单独的进程中加载的托管程序集
signtool.exe;winapp 自己的自包含运行时不满足它。 如果签名失败并出现运行时加载错误,请安装 https://dotnet.microsoft.com/download 它。 -
Microsoft Visual C++ Redistributable (x64) 。 Azure签名客户端库取决于 VC++ 运行时,并且由于 winapp 下载原始 NuGet 包而不是官方客户端工具安装程序,因此不会自动安装此依赖项。 即使存在.NET和 SignTool,清理计算机也能加载失败。 如果签名失败,请安装最新的 x64 可再发行组件 https://aka.ms/vs/17/release/vc_redist.x64.exe ,并
0xc000007b显示“应用程序无法正确启动”或 dlib 中缺少 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
create-external-catalog
生成包含 CodeIntegrityExternal.cat 指定目录中可执行文件哈希的目录文件。 此目录与 MSIX 稀疏包清单(AllowExternalContent)中的 TrustedLaunch 标志一起使用,以允许执行包本身不包含的外部文件。
这类似于在对 MSIX 包进行签名时创建signtool.exe的方式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 包时,请使用此命令。 典型的工作流为:
-
winapp manifest generate --template sparse— 使用 创建稀疏清单AllowExternalContent -
winapp create-external-catalog ./bin- 为应用的可执行文件生成代码完整性目录 -
winapp pack— 将清单、资产和目录打包到 MSIX 中
工具
直接访问Windows SDK工具。 使用 Microsoft.Windows 中提供的工具。Sdk。BuildTools
winapp tool <tool-name> [tool-arguments]
可用工具:
-
makeappx- 创建和操作应用包 -
signtool- 对文件进行签名并验证签名 -
mt- 并行程序集的清单工具 - 以及来自 Microsoft.Windows 的其他 Windows SDK 工具。Sdk。BuildTools
示例:
# Use signtool to verify signature
winapp tool signtool verify /pa MyApp.msix
签名验证
生成工具从 NuGet 下载,然后执行,因此 winapp 会在运行它之前立即检查每个工具是否有有效的Microsoft验证码签名。 证书必须将公司命名为签名组织Microsoft。 这适用于 shells out 到 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...– 要直接传递到msstoreCLI 的参数。 有关可用命令和选项,请参阅 MSStore CLI 文档 。
功能:
- 确保下载Microsoft Store开发人员 CLI(
msstore),并在系统上可用。 - 将所有参数转发到
msstoreCLI。 - 直接在终端中运行显示输出的命令。
示例:
# 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 SDK 组件的路径。
winapp get-winapp-path [options]
它返回的内容:
-
.winapp工作区目录的路径 - 包安装目录
- 生成的标头位置
目标
运行命令、复制文件、检查状态或捕获整个来宾桌面。
每个谓词 sandbox 都采用其第一个参数。
snapshot除了,这些命令可以准备或启动沙盒。 有关先决条件、权限、生命周期和恢复,请参阅Windows沙盒执行。
target exec
以来宾用户身份运行命令。
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
它不会重新连接客户端或修复代理。 没有正在运行的沙盒是成功的结果,而不是错误。 请参阅 “检查沙盒 ”,了解如何解释就绪情况和进程 ID。
目标屏幕截图
将来宾桌面的本机像素大小捕获为主机 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,但捕获桌面而不是一个应用。 对于无人参与的 CLI 使用,首选正 --duration-sec 值;npm 帮助程序需要 durationSec。 有关部分证据和捕获就绪失败,请参阅 沙盒捕获 。
find-ui
代理优先。
find-ui主要针对 AI 编码代理构建 - 它允许代理从发货库编译 WinUI 标记,而不是发明它,并使--json每个结果(以及每个故障)计算机可读。 它同样适合手动键入。
在 WinUI 控件和示例中搜索工作代码示例。 仅限 WinUI:corpus 是 WinUI 3 库和Windows社区工具包(以及几个特选的核心模式),它不包括WPF、WinForms 或其他 UI 框架。 第三个来源 是 microsoft-ui-reactor ReactorGallery,是 选择加入:它被排除在正常搜索之外,并且仅在传递 --source reactor 时进行搜索(其仅限 C#的声明性示例不会粘贴到标准 XAML 应用中,因此仅在生成 Reactor/MVU 项目时才访问它)。
winapp find-ui "<query>" [options]
库、工具包和 Reactor corpora 在 CLI 内部交付,因此 find-ui 无需网络访问,包括首次在代理沙盒中运行或阻止的公司代理 raw.githubusercontent.com后面运行。 当GitHub可访问时,CLI 会从中刷新并缓存每个用户的结果<global .winapp>/cache/find-ui;内置corpus 只是一个楼层,从不具有上限。 缓存的数据最多每 24 小时刷新一次,或者按需刷新 --refresh。
每次生成稳定版本时,内置语料库都会从GitHub中重新提取,并且刷新会停止发布版本,而不是悄悄地传送旧数据 — 面包师通过相同的代码路径--refresh提取,因此失败意味着实时刷新也断开,并且值得在发货前进行调查。 发布仍可针对以前提交的corpus 进行剪切,但只能作为显式替代进行。 当从库/工具包/Reactor corpora 的内置副本提供结果时, find-ui 在 stderr 和 --json 输出上显示结果会携带 "corpus": "embedded" (其他值: "network" 用于新提取, "cache" 用于本地缓存)。 仅核心请求 --source core(或 --id 所有核心模式集)也会报告 "embedded" ,因为特选的核心模式已编译到 CLI 中,并且永远不会提取;它不会打印过时的通知,因为 --refresh 无法更改它们。 只要 corpus 提供结果,就会报告该字段;仅当完全无法加载料料库时,该字段才缺席。
选项:
-
--id <id>- 提取代码(库/工具包返回 XAML 和/或 C# ;Reactor 是仅限 C#的,也是先前搜索中的一个或多个方案 ID 的先决条件说明(例如gallery-tabview-1)。 重复。 ID 不区分大小 写 ,GALLERY-TABVIEW-1解析与gallery-tabview-1. -
--list- 列出每个可发现的控制/示例 ID 而不是搜索(库 + 工具包 + 核心;不包括选择加入 Reactor 源)。 -
--source <gallery|toolkit|reactor|core>- 将搜索结果限制为单个源。 (仅搜索 - 对 .) 无效--list/--id反应堆是选择加入的 - 它被排除在正常搜索之外,因此--source reactor是搜索它的唯一方法。 -
--max <N>- 要返回的最大匹配控件数(默认值:3)。 仅适用于搜索;忽略了 .--list/--id -
--refresh- 绕过本地缓存并从GitHub重新提取 WinUI corpus。 -
--json- 发出结构化 JSON(代理友好)。 对于搜索,每个匹配项source包含一个scenarios数组,controldescriptionscore其条目包含每个方案id;header对于--id完整代码。 在--json每次失败( 包括参数/分析器错误(如非整数--max)下,都会以非零退出代码在 stdout 上作为平面{"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 为 in --json 和注释:
-
project- 当前目录中的项目(或--project/--project-dir)。 涵盖Windows SDK、Windows 应用 SDK和项目自己的 NuGet 包。 Windows 应用 SDK元数据是项目引用的发布:如果计算机安装了较新的Windows 应用运行时,则会发出警告并将其排除,find-api而不是确认项目无法编译的类型。 -
sdk- 计算机范围的Windows SDK + Windows 应用 SDK元数据,在当前目录不包含项目且无解决方案时自动使用。 这样find-api就可用于在任何项目存在之前浏览 API,并且无需网络访问。 它故意 不包含 第三方 NuGet 包,因此不会在此范围内找到社区工具包的类型。
来自没有项目且没有解决方案的sdk目录中的查询始终由范围回答-从不由任何项目在共享缓存中编制索引,因此结果永远不会依赖于不相关的全局状态。 传递--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>,与单个索引项目匹配的名称将失败,而不是为当前目录编制索引。
Batching.search、 members和enumscheck-property接受多个主题在一个调用中。 对于 AI 代理来说,这是单一最大的成本杠杆:查找的边际成本由往返(每个呼叫重新发送整个对话)为主,而不是有效负载的大小,因此一个调用回答十个问题远低于十个呼叫。
-
单个主题返回它始终在文本和
--json文本中始终具有的有效负载形状。 -
两个或多个 主题返回一个信封,
{ "count": N, "results": [ ... ] }其中--json每个元素都是普通的单主题有效负载;check-property添加missingCount。 文本输出在一个范围标头下按顺序呈现每个主题。 -
check-property对 一种类型的属性进行批处理:第一个参数是类型,它是属性之后的每个参数。 在批处理模式下,存在的属性打印单 ✅ 行;仅打印未命中的完整详细信息。 - 仅当每个主题解析并被发现时,批处理才会退出
0,因此批处理仍可以安全地关闭代码生成。
搜索排名。 与类型名称完全匹配的查询在部分匹配项之前进行排名,当多个命名空间共享短名称时,仅将确切名称冲突列为不明确 -- 一个查询(如 NavigationView 报告定义确切类型的少数命名空间,而不是包含类似命名符号的每个命名空间)。 模棱两可列表遵循 --max,正常结果仍打印在下方。
键入 name.members, check-property并 enums 接受短名称(NavigationView)或完全限定的名称(Microsoft.UI.Xaml.Controls.NavigationView)。 当短名称由新式Microsoft.*类型及其旧Windows.*版 UWP 孪生共享时,Microsoft.*类型答案(即Windows 应用 SDK应用使用的投影),解析的完全限定名称始终显示。 任何其他冲突都退出非零,并列出候选项,而不是猜测。
方法签名。 将按照编写调用的方式打印签名:使用 显示对类型而不是实例static调用的方法,并用实际需要的outin关键字(或ref)显示按引用参数。 因此 TryGetValue , Boolean TryGetValue(String key, out String value)读取,它编译为写入。
选项:
-
--max <n>- 命名空间分组搜索结果的最大数量(默认值5;仅搜索)。 此外,还会限制歧义列表,因此在多个命名空间之间发生冲突的简短查询保持可读性。 -
--filter <text>- 缩小列表范围members,并在enums成员/值名称上与不 区分大小写的子字符串 匹配。 最适合具有数百个成员的类型。 大多数枚举足够小,足以转储整个(甚至Symbol,WinUI 中最大的值为 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或sdk)projectName和projectDir(SDK 范围不存在)应答的索引 ,项目名称在目录之间并不唯一,可靠标识也是如此projectDir。 在--json每次失败( 包括参数/分析器错误(如非整数--max)下,都会以非零退出代码在 stdout 上作为平面{"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假(由 false 表示)。declaringType
始终报告省略的内容(hiddenDependencyPropertiesdescriptionsOmitted以及一个 hint in--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 项目文件的项目。 电子应用(或任何其他非.NET应用驱动winapp.yaml)没有.csproj,因此没有project.assets.json。
find-api从该winapp restore写入中.winapp/winmds.lock.json为它编制索引,该写入记录相同内容:每个解析的包、其版本及其.winmd贡献的文件。 此类项目以目录命名,在重写锁定文件时其索引会过时。 一个目录,其中包含一个 .csproj 和一个 winapp.yaml 目录,该目录是从 .csproj中编制索引的,这是项目编译时所针对的更精确的说明。
当索引不完整时,负答案是限定的。 如果无法读取包的元数据,则“没有此类类型”和“从未编制过索引的包”看起来完全相同,并且当它实际上是第二个针对你被告知的 API 生成代码时,它的作用就不存在了。 因此,每个负答案(包括 search 返回零结果的答案)都带有一个注释,指出索引是部分的,指向点 winapp find-api refresh。 积极答案不受影响。
泛型类型名称。 元数据存储具有 arity 后缀(IAsyncOperation`1)的泛型类型,这不是任何人写入它们的方式。
members、 enums和 check-property 接受每个窗体: IAsyncOperation, IAsyncOperation<StorageFile>以及 IAsyncOperation`1 所有解析为同一类型。 裸名称与任何 arity 匹配;一个表示法(在任一表示法中)必须匹配,因此 Holder<A, B> 不会解析为单参数 Holder<T>。
--json 有效负载省略诊断。 缓存文件路径仅 --verbose 显示在(匹配的文本输出(其中它们已是仅详细)和空建议数组被省略,而不是序列化为 []。
退出代码:search 没有命中、 check-property 缺少属性和 enums 非枚举类型上的所有退出非零 -- 门代码生成和 CI 检查它们。 如果 任何 主题失败,批处理调用将退出非零。 只读属性 不是 故障 ,它存在,因此 check-property 退出 0 并在输出(writable: false in) --json中标记它。 属性 init 报告 writable: false 的原因相同:它可以在对象初始值设定项中设置,并且其签名显示 { get; init; },但之后分配该属性不会编译。
相关:find-api 回答“此 API 是否存在以及其成员是什么?”;用于 find-ui 查找控件的工作 WinUI 示例。
node generate-bindings
(仅在 NPM 包中可用)为 Windows 应用 SDK API 生成 JS 绑定。 绑定由 "winapp": { "jsBindings": {...} } 命名空间 package.json 声明并写入 .winapp/bindings/。
npx winapp node generate-bindings [options]
选项:
-
--verbose,-v- 启用详细每文件 codegen 输出 -
--quiet,-q- 取消进度和信息输出
功能:
-
winapp.jsBindings读取package.json块以及winmds.lock.json最后winapp restore一个写入的块,然后将类型化的.js+.d.ts绑定发出到.winapp/bindings/ -
不修改
package.json— 它是被动重新生成器。winapp.jsBindings在启用 JS 绑定期间添加块和@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配置选项。
node 创建插件
(仅在 NPM 包中可用)使用 Windows SDK 和Windows 应用 SDK集成生成本机 C++ 或 C# 加载项模板。
npx winapp node create-addon [options]
选项:
-
--name <name>- Addon name (default: “nativeWindowsAddon”) -
--template- 选择加载项的类型。 选项为cs或cpp(默认值:cpp) -
--verbose- 启用详细输出
功能:
- 创建带有模板文件的插件目录
- 使用 Windows SDK 示例生成 binding.gyp 和 addon.cc
- 安装所需的 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
节点 添加 Electron 调试 身份
(仅在 NPM 包中可用) 使用稀疏打包将应用标识添加到 Electron 开发过程。 需要 Package.appxmanifest(创建一个包含 winapp init 或 winapp manifest generate 如果没有 Package.appxmanifest)。
重要
稀疏打包 Electron 应用程序存在一个已知问题,导致应用在启动时崩溃或不呈现 Web 内容。 此问题已在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]
选项:
| 选项 | 说明 |
|---|---|
--manifest <path> |
自定义 Package.appxmanifest 的路径(默认值:当前目录中的 Package.appxmanifest) |
--no-install |
不要安装或修改依赖项;仅配置 Electron 调试标识 |
--keep-identity |
保留清单标识原样,而不附加 .debug 到包名称和应用程序 ID |
--verbose |
启用详细输出 |
功能:
- 为 electron.exe 进程注册调试标识
- 在电子开发中启用测试需要标识的 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
节点清除电子调试身份指令 (node clear-electron-debug-identity)
(仅在 NPM 包中可用) 通过从备份还原原始 electron.exe,从 Electron 调试过程中删除包标识。
npx winapp node clear-electron-debug-identity [options]
选项:
| 选项 | 说明 |
|---|---|
--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 环境变量。
在 cmd 中:
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 或 restore以下命令时,Winapp 将自动创建此目录。
更新检查
winapp CLI 会定期检查新版本,并在更新可用时显示一行通知。 此检查在后台运行,不会向命令添加任何延迟。
更新检查在 CI 环境中自动禁用(GitHub Actions、Azure Pipelines等)。
若要手动禁用更新检查,请将 WINAPP_CLI_UPDATE_CHECK 环境变量设置为 0。
在 cmd 中:
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 工作流。
ui
使用 UI 自动化 (UIA) 检查并与其运行Windows应用 UI 进行交互。
winapp ui [command] [options]
命令:
-
status- 连接到应用并显示信息 -
inspect- 查看元素树 -
search- 按选择器查找元素 -
get-property- 读取元素属性 -
get-text/get-value- 从元素读取值/文本(TextPattern、ValuePattern 或 Name) -
screenshot- 将窗口/元素捕获为 PNG(多个窗口窗体一个标记的复合 PNG;请参阅 捕获范围) -
record- 将窗口/元素区域录制到 H.264 MP4 视频(Windows图形捕获 + 媒体基础) -
invoke- 激活元素(单击、切换、展开) -
click- 通过鼠标模拟单击元素(对于不支持调用的控件) -
hover- 将鼠标移动到元素以触发工具提示、浮出控件和悬停状态(默认停留:800 毫秒) -
drag- 通过元素选择器或屏幕x,y坐标将鼠标从一个点拖动到另一个点(重新排序、调整大小、滑块、拖放) -
touch- 在元素中心或屏幕x,y坐标处注入合成触摸手势(点击、双击、长按、轻扫、收缩、拉伸) -
pen- 注入合成笔/触笔输入 - 具有可配置压力、倾斜和橡皮擦模式的点击和墨迹笔划 -
send-keys- 将合成键盘输入(命名键、组合、原始 vk=0xNN 或文本文本)发送到窗口 -
set-value- 在可编辑元素上设置值(文本、数字);回退到仅限 TextPattern 的 rich-edit 控件的 LegacyIAccessibleput_accValue -
focus- 移动键盘焦点 -
scroll-into-view- 滚动元素可见 -
wait-for- 等待元素状态 -
list-windows- 列出应用的所有窗口 -
get-focused- 报告当前聚焦的元素 -
yield- 释放当前工作流的 UI 轮次;requiresWINAPP_UI_WORKFLOW_ID
选项:
-
-a, --app <app>- 目标应用(名称、标题或 PID) -
-w, --window <hwnd>- HWND 的目标窗口(稳定) -
--on <target>- 在 ;名称、PID 和窗口句柄中sandbox运行任何ui谓词引用来宾。 输出将传送到主机。 请参阅 沙盒 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-edge64-4096(默认为 1280),并具有 1 GiB 帧数据上限。
其中 --json,最终结果包括输出路径、维度、编解码器、捕获模式、节奏、停止原因、可选 frameArtifacts和警告。
已知限制: 在弹出窗口中记录呈现在其自己的顶级窗口(WinUI/XAML 浮出控件、教学提示、工具提示)中的 特定元素 可能会改为捕获基础主窗口。 记录整个窗口,或按照 弹出窗口的屏幕截图覆盖工作流 进行操作。 在 #646 中跟踪。
有关完整文档,请参阅 docs/ui-automation.md。