winapp CLI(Windows App Development CLI)は、Windows SDKとWindows App SDKの導入、パッケージID(package identity)の付与、マニフェスト生成、開発用証明書の作成、MSIXパッケージ化までを1つのコマンドに束ねたMicrosoft製のツールです。Visual Studioを前提にせず、Electron・Rust・Tauri・Flutter・C++・.NETのいずれからでも同じ手順でWindowsのネイティブ機能に手を伸ばせる点が特徴です。2025年11月に最初のリリースが出て、2026年8月19日公開のv0.6.1でトップレベル19コマンドまで広がりました。ただし公式の位置づけは現在もPublic Previewで、破壊的変更があり得ます。この記事ではv0.6.1のコマンド定義を一次情報で照合し、導入から各コマンドの使い分けまでを整理します。参照した資料は、リリースタグv0.6.1のコマンド定義(cli-schema.json)・使用ガイド(usage.md)・UI Automationガイドです。
まとめ:winapp CLIを触る前に押さえる4点
- Windows専用のツールです。npmパッケージの対応OS指定は
win32だけで、macOSやLinuxでは動きません。npm経由で入れる場合のみNode.js 18以上が必要で、WinGet版はNode.jsに依存しません。 - 入口は
winapp init。カレントディレクトリからプロジェクト種別(Electron・Tauri・Flutter・.NET・Rust・C++)を自動判別し、SDKの取得・マニフェスト生成・証明書作成までまとめて行います。 - デバッグは
winapp runが基本で、Electronのようにexeがnode_modules側にある構成や、sparseパッケージの挙動を検証する場合にはwinapp create-debug-identityを使います。ここを取り違えると、パッケージIDが必要なAPIのテストが通りません。 - Microsoft Storeへの提出では、winappがmsstoreを呼び出します。
winapp storeはMicrosoft Store Developer CLI(msstore)を取得して引数をそのまま渡すラッパーで、提出そのものはmsstore側の機能です。
掲載コマンドはv0.6.1の公式資料と照合した例です。本記事の作成環境はmacOSのため、Windows上での実行検証は行っていません。
winapp CLIの役割と対応範囲
リポジトリは microsoft/winappCli で、ライセンスはMITです。リポジトリ作成は2025年7月30日、最初の公開リリースは2025年11月4日のv0.1.0でした。2026年9月23日時点のスター数は1,268です。
公式の説明文では「Windows SDKの管理、パッケージング、アプリID・マニフェスト・証明書の生成、ビルドツールの利用を、任意のアプリフレームワークに対してひとつのCLIで扱う」と定義されています。狙いはVisual Studioの置き換えではなく、Visual Studioを使わない開発者がWindows固有の仕組みに接続するための導線です。
パッケージIDによるWindows機能との統合
Windowsの多くのAPIは、アプリに「パッケージID」が付与されていることを前提にしています。パッケージIDやマニフェストを使って統合できる機能の例を挙げます。ただし、通知や独自URIスキームなどには、パッケージIDなしで利用できる実装方式もあります。
- 対話型のネイティブ通知(トースト通知)とその管理
- エクスプローラー・タスクバー・共有シートなどシェルへの統合
- プロトコルハンドラー(
yourapp://形式のURI)とWeb-to-appリンク - オンデバイスAI(ローカルLLM、テキスト・画像のAI API)
- ファイルの種類の関連付け、スタートアップタスク、バックグラウンドタスク
- カメラ・マイク・位置情報への同意ベースのアクセス
従来これらを試すには、SDKの入手からマニフェスト作成、証明書の発行、パッケージ登録まで手作業の工程が並びました。公式READMEは、winapp CLI導入前が12手順、導入後は init・create-addon・add-electron-debug-identity・pack の4コマンドになると説明しています。
対応するフレームワークと動作要件
公式に入門ガイドが用意されているのは.NET(WPF・WinForms含む)、C++、Electron、Rust、Tauri、Flutter、.NET MAUIです。リポジトリのサンプルにはこれらに加えてWinUI 3アプリ、Node.jsからWinUI 3コントロールを生成する例、Electron+Windows MLの例が含まれます。
配布形態は4通りあります。スタンドアロンのCLI(WinGet・GitHub Releases)、npmパッケージ @microsoft/winappcli、NuGetパッケージ Microsoft.Windows.SDK.BuildTools.WinApp、そしてVS Code拡張です。npm版のみ node 系コマンドとJSバインディング生成が使えます。
インストール:winget・npm・CI・VS Code拡張
WinGet(スタンドアロン版)
最も簡単な導入経路です。winget-pkgsリポジトリに登録されているパッケージIDは Microsoft.WinAppCli で、マニフェストは0.1.4.0などの旧版から0.6.1まで公開されています。
winget install Microsoft.winappcli --source winget
PowerShellの Microsoft.WinGet.Client モジュールを使う場合は次の形です。
Install-WinGetPackage Microsoft.winappcli
npm(Electron・Node.js向け)
Electronプロジェクトでは開発依存として導入できます。再現可能な版管理には package-lock.json もコミットし、CIでは npm ci を使います。package.json にも厳密な版を保存する場合は --save-exact を指定します。実行ファイル名は winapp で、npx winapp として呼び出します。
npm install @microsoft/winappcli --save-dev
npx winapp --help
npmの最新版は0.6.2(2026年9月23日の確認時点。npmレジストリ上の公開日は2026年8月19日)です。GitHub Releasesの最新タグはv0.6.1なので、npm側が1パッチ分先行している状態にあります。
CIパイプラインとVS Code拡張
GitHub ActionsとAzure DevOpsでは、ランナーへCLIを導入する専用アクション microsoft/setup-WinAppCli が公開されています。エディタ側からは、VS Code拡張(Microsoft-WinAppCLI.winapp)がプロジェクトの初期化・パッケージID付きデバッグ・パッケージ化・署名をUIから実行でき、F5キーでIDを付けた状態のアプリ起動とデバッガーのアタッチまで行います。拡張のソースは microsoft/WinAppVSCE です。
プロジェクトの初期化:winapp init
winapp init はWindowsアプリ開発に必要な設定をまとめて用意するコマンドです。既定の動作は、既定アセット付きの Package.appxmanifest 生成、Windows SDKとWindows App SDKのダウンロード、プロジェクション(C++/WinRTヘッダー)の生成、開発者モードの有効化、.gitignore の更新です。SDKの版を管理する設定として winapp.yaml が作られ、以後 restore・update がこれを参照します。
# カレントディレクトリを初期化(対話式)
winapp init
# 対話を飛ばして既定値で初期化
winapp init ./my-project --use-defaults
# プレビュー版SDKを使う
winapp init --setup-sdks preview
--setup-sdks は stable(既定)・preview・experimental・none の4値です。RustやTauriのようにSDKバインディングを自前で持つプロジェクトでは none を指定し、この場合 winapp.yaml は作られません。
プロジェクト種別の自動判別
ディレクトリ引数を省略すると、カレントディレクトリ以下を幅優先で探索して対応プロジェクトを最大10件まで探します。判定の手がかりは次のとおりです。
| フレームワーク | 判定に使うファイル |
|---|---|
| Tauri | 1階層下の tauri.conf.json |
| Electron | package.json の依存に electron がある |
| Flutter | プロジェクト直下の pubspec.yaml |
| .NET | プロジェクト直下の .csproj |
| Rust | プロジェクト直下の Cargo.toml |
| C++ | プロジェクト直下の CMakeLists.txt |
探索は node_modules・bin・obj・.git など通常除外されるディレクトリを飛ばします。CIのように標準入力が対話不可の環境では自動的に既定値が使われ、「Non-interactive environment detected. Using default values.」という警告が出ます。
.csprojが見つかった場合は.NET専用の流れに切り替わり、TargetFramework をWindows対応のTFMへ更新し、Microsoft.WindowsAppSDK と Microsoft.Windows.SDK.BuildTools を PackageReference として .csproj に直接追加します。この経路では winapp.yaml は作られず、パッケージの復元は dotnet restore が担います。
既存exe用のsparseマニフェスト生成
すでに動いているデスクトップアプリへ、SDKを入れずにパッケージIDだけを足したい場合は --exe と --sparse を組み合わせます。--exe を --sparse なしで指定するとエラーになります。
winapp init --exe ./bin/Release/net8.0-windows/MyApp.exe --sparse --use-defaults
パッケージ名・発行者・説明・バージョンはexeのFileVersionInfoから推定され、sparse/ フォルダーに appxmanifest.xml とプレースホルダーのアセットが書き出されます。生成されたアセットはMSIXに同梱されず、実行時にアプリのインストール先(外部コンテンツの場所)から解決されるため、アプリ本体と一緒に配布します。initだけではID付与は完了せず、続いてwinapp packで署名済みのidentity MSIXを作成し、winapp embed-identityでexeに識別情報を埋め込み、Add-AppxPackageの-ExternalLocation指定で登録します。
主要コマンド一覧
v0.6.1のコマンド定義(docs/cli-schema.json)にあるトップレベルコマンドは19個です。用途別にまとめると次のようになります。
| 分類 | コマンド | 役割 |
|---|---|---|
| セットアップ | new |
公式テンプレートからWinUIアプリを新規作成(.NET SDKが必要) |
| セットアップ | init |
SDK導入・マニフェスト・証明書をまとめて用意 |
| セットアップ | restore |
winapp.yaml の版のままSDKパッケージを再導入 |
| セットアップ | update |
新しいSDK版を確認し winapp.yaml を更新して再導入 |
| ID・デバッグ | run |
ビルド出力をルーズレイアウトで登録して起動(PIDを返す) |
| ID・デバッグ | create-debug-identity |
単一exeにsparseパッケージでIDを付与 |
| ID・デバッグ | embed-identity |
exeのSxSマニフェストへ <msix> 要素を埋め込む |
| ID・デバッグ | unregister |
開発モードで登録したサイドロードパッケージを解除 |
| ID・デバッグ | manifest |
マニフェストの生成・アセット更新・実行エイリアス追加 |
| パッケージ化 | package(別名 pack) |
ビルド済みフォルダーからMSIX/MSIXバンドルを作成 |
| 署名 | cert |
開発用証明書の生成・確認・インストール |
| 署名 | sign |
MSIXやexeをPFX証明書で署名 |
| 署名 | az-sign |
Azure Trusted Signingで署名(ローカルPFX不要) |
| 署名 | create-external-catalog |
CodeIntegrityExternal.cat を生成 |
| ツール | tool(別名 run-buildtool) |
makeappx・signtool・mt などWindows SDKツールを直接実行 |
| ツール | store |
Microsoft Store Developer CLIを取得して引数を転送 |
| ツール | get-winapp-path |
.winapp ディレクトリのパスを出力 |
| 探索 | find-ui |
WinUIコントロールとサンプルから動くコード例を検索 |
| 自動操作 | ui |
UI Automationで実行中アプリを検査・操作(21サブコマンド) |
グローバルオプションは --help・--version・--cli-schema が、公開スキーマのルート直下に定義されています。各コマンドには共通のログ制御用オプションとして --verbose・--quiet もあります。--cli-schema はコマンド・オプション・引数の全構造をJSONで出力するもので、公式の説明でも「ツール連携、スクリプト、LLM連携のため」と明記されています。CIでコマンドの有無を確認したり、生成AIにコマンド体系を渡したりする用途で使えます。
winapp --cli-schema > cli-schema.json
なお旧来の解説記事では winapp cert create という表記が見られますが、v0.6.1のコマンド定義に cert create は存在しません。証明書の生成は winapp cert generate です。
デバッグ:runとcreate-debug-identityの使い分け
パッケージIDが必要なAPIを開発中に試す方法は2つあり、公式ドキュメントは使い分けを明示しています。
winapp run は、ビルド出力フォルダーからルーズレイアウトのパッケージを作り、Windows.Management.Deployment.PackageManager APIで登録してアプリを起動します。実際のMSIXインストールに近い状態を再現でき、デバッガーをアタッチするためのプロセスIDを返します。.NET・C++・Rust・Flutter・Tauriでは、こちらが推奨されるデバッグ手段です。
# ビルド出力を登録して起動
winapp run ./bin/Debug
# プロジェクトモード(.csproj/.sln をビルドしてから起動)
winapp run .
# 登録のみ実行。続いてIDEなどからアプリを起動し、デバッグする
winapp run ./bin/Debug --no-launch
対して winapp create-debug-identity は単一のexeにsparseパッケージでIDを結び付けます。exeがアプリのコードと別の場所にある構成、たとえばElectronで electron.exe が node_modules 配下にある場合や、sparseパッケージの挙動そのものを検証したい場合に使います。
winapp create-debug-identity ./bin/MyApp.exe
winapp create-debug-identity ./dist/app.exe --manifest ./custom-manifest.xml
既定ではパッケージ名とアプリケーションIDの末尾に .debug が付きます。マニフェストのIDをそのまま使いたい場合は --keep-identity を指定します。マニフェストや Assets/ を変更したら再実行が必要です。どちらの方法で登録した開発用パッケージも、winapp unregister で解除できます。
クラッシュ解析まで含めたデバッグ
winapp run --debug-output は OutputDebugString と初回例外を拾い、アプリがクラッシュした場合はミニダンプを自動取得して例外の型・メッセージ・スタックトレースを表示します。.NETのクラッシュは外部ツール無しで即座に解析され、ネイティブ(C++/WinRT)はモジュール名とオフセットが出ます。--symbols を足すとMicrosoft Symbol Serverからシンボルをダウンロードし、関数名まで解決します。
ただし1つのプロセスに同時にアタッチできるデバッガーは1つだけなので、--debug-output を使っている間はVisual StudioやVS Codeのデバッガーを併用できません。併用したい場合は --no-launch で登録だけ行います。
MSIX化と署名、Microsoft Storeへの提出
winapp packによるMSIX生成
winapp pack(winapp package の別名)は、ビルド済みのフォルダーからMSIXを生成します。マニフェストが対象フォルダーかカレントディレクトリに必要です。
# マニフェストを自動検出してパッケージ化
winapp pack ./dist
# 証明書を生成・インストールしつつ自己完結型で作る
winapp pack ./dist --generate-cert --install-cert --self-contained
--self-contained はWindows App SDKのランタイムを同梱するオプションです。マニフェスト内の $targetnametoken$ は、--executable で指定するか、入力フォルダー直下にexeが1つだけあれば自動で解決されます。0個または複数あるとエラーになり、明示を求められます。
複数の入力フォルダーを渡すと、アーキテクチャごとのMSIXを含む .msixbundle になります。各フォルダーのアーキテクチャは主実行ファイルのPEヘッダーから自動判定され、スライス間でIdentity・Capabilities・Dependenciesが一致しているかを検証します。
# Microsoft Store提出用の未署名バンドル
winapp pack ./publish/x64 ./publish/arm64
# サイドロード用の署名済みバンドル
winapp pack ./publish/x64 ./publish/arm64 --cert ./devcert.pfx
証明書の生成と署名
開発用証明書は winapp cert generate で作ります。発行者はマニフェストと一致している必要があり、--manifest を渡せば自動で抽出されます。有効期間の既定は365日、パスワードの既定は password です。
# 発行者を指定して生成
winapp cert generate --publisher "CN=My Company" --output ./mycert.pfx
# 中身を確認してから機械可読で扱う
winapp cert info ./mycert.pfx --json
# 端末に信頼させる(管理者権限が必要)
winapp cert install ./mycert.pfx
署名は winapp sign です。本番向けにローカルのPFXを持ち回りたくない場合は、Azure Trusted Signingを使う winapp az-sign があります。実行にはAzure側の署名アカウント・証明書プロファイル・署名権限と認証情報に加え、端末にx64版.NET 8以降のランタイムとVisual C++再頒布可能パッケージが必要です。これらはwinappの導入だけでは揃いません。
winapp sign MyApp.msix --cert ./mycert.pfx
winapp az-sign ./app.msix
winapp storeはmsstore CLIのラッパー
Microsoft Storeへの提出は、winapp CLI自身が行うわけではありません。winapp store はMicrosoft Store Developer CLI(msstore)が未取得なら先にダウンロードし、渡された引数をそのまま msstore へ転送して実行するコマンドです。提出処理そのものは msstore 側の機能で、使えるサブコマンドとオプションも msstore のドキュメントに従います。
# Partner Centerのアプリ一覧
winapp store app list
# パッケージを提出する
winapp store publish ./myapp.msix --appId <your-app-id>
Partner Centerのアカウント作成とアプリ登録、認証の設定を済ませていれば、提出操作そのものは winapp store publish の1コマンドで呼び出せます。winappが肩代わりするのは msstore の導入と呼び出しまでで、提出後の審査を含むストア側の手続きは従来どおりです。
Electron・Node.js専用のnodeコマンド群
node 配下の4コマンドはnpmパッケージ経由でのみ利用でき、WinGetで入れたスタンドアロン版には現れません。npx winapp から呼び出します。
| コマンド | 役割 |
|---|---|
node create-addon |
C++またはC#のネイティブアドオン雛形を生成 |
node generate-bindings |
package.json の winapp.jsBindings から型付きの .js/.d.ts を .winapp/bindings/ へ生成 |
node add-electron-debug-identity |
Electronの開発プロセスにsparseパッケージでIDを付与 |
node clear-electron-debug-identity |
上記で付与したIDを取り消す |
JSバインディングを使うと、レンダラープロセスからネイティブのファイルピッカーやトースト通知、オンデバイスLLM(Phi Silica)、Windows MLによるONNXモデル実行を呼び出せます。Phi Silicaの利用には対応するCopilot+ PCと、マニフェストのsystemAIModels制限付き機能宣言が必要です。公式例はメインプロセスから呼び出し、必要に応じてpreloadやIPC経由でレンダラーに公開する構成です。有効化は初期化時の --add-js-bindings で行い、ランタイムとして @microsoft/dynwinrt(2026年9月時点で 0.1.0-preview.21)が追加されます。
npx winapp init . --use-defaults --add-js-bindings
npm install
npx winapp node generate-bindings
generate-bindings は package.json を書き換えない再生成専用のコマンドで、winapp.jsBindings ブロックが無い場合は即座に失敗します。ブロックの追加は init の役目です。
Electron特有の注意点として、公式ドキュメントはsparseパッケージ化したElectronアプリが起動時にクラッシュする、またはWebコンテンツが描画されない既知の問題を挙げています。Windows側では修正済みですが、外部のWindows端末にはまだ行き渡っていないとされ、デバッグ目的に限り --no-sandbox でサンドボックスを無効化する回避策が案内されています。この問題は完全なMSIXパッケージ化には影響しません。
winapp ui:UI Automationによるアプリの検査・操作
v0.6.1には、実行中アプリを検査・操作する winapp ui もあります。Windows UI Automation(UIA)を通じて実行中のアプリを検査・操作するコマンド群で、サブコマンドは21個あります。対象はWPF・WinForms・Win32・Electron・WinUI 3のいずれでも構いません。
# UIツリーを表示する
winapp ui inspect -a notepad
# 要素を検索する
winapp ui search Button -a notepad
# 要素を実行する(Invoke/Toggle/SelectionItem/ExpandCollapse を順に試行)
winapp ui invoke Close -a notepad
# スクリーンショットを撮る
winapp ui screenshot -a notepad
対象アプリの指定は -a でプロセス名・ウィンドウタイトル・PIDのいずれでも可能です。タブやタイトルの変更で取り違えたくない場合は、winapp ui list-windows でHWNDを調べて -w で固定します。
CIで使える動詞と使えない動詞
ここが実務上の分かれ目です。21のサブコマンドは、UIAのパターンを通じて操作するものと、OSレベルの入力を合成するものに分かれます。
| 種別 | 該当コマンド | ロック画面・ヘッドレス |
|---|---|---|
| UIAパターン経由 | inspect/search/get-property/get-value/wait-for/set-value/invoke/screenshot/scroll(方向・位置指定) |
動作する |
| 入力を合成 | click/hover/drag/touch/pen/scroll --wheel/send-keys --via send-input |
no_interactive_desktop で失敗 |
入力を合成する動詞は、ロック解除された対話的なデスクトップと、対象ウィンドウが前面にあることを要求します。CIで回すなら前者を優先し、後者は実際の入力が不可欠な場面に限るのが公式の推奨です。send-keys の既定の転送方式は post-message で、こちらは対象ウィンドウのキューへ直接送るためロック中でも使えます。ただしWinUI 3やUWPのXAMLコントロールは子ウィンドウを持たないため post-message では届かず(警告を出して終了コード0になります)、この場合は --via send-input が必要です。なお入力合成の直前には対象要素を再解決し、まだアニメーション中や移動中であれば target_moved として拒否するので、何もない場所をクリックする事故は起きにくくなっています。
winapp ui record はウィンドウや要素の領域をH.264のMP4として録画します。--duration-sec 0 でCtrl+Cまで録り続け、--frames を付けるとタイムスタンプ付きJPEGと frames.ndjson も書き出されます。ポップアップ内の特定要素を録画すると背後のメインウィンドウが写る既知の制約があり、この場合はウィンドウ全体を録るか、静止画なら ui screenshot --capture-screen を使います。
AIコーディングエージェントとの連携
リポジトリにはAgent Plugins 1.0仕様に準拠したプラグインが同梱されており、GitHub CopilotとClaude Codeのプラグインマーケットプレイス経由で配布されています。
copilot plugin install microsoft/WinAppCli
claude plugin marketplace add microsoft/WinAppCli
claude plugin install winappcli@winappcli
find-ui もこの文脈のコマンドです。WinUI 3 GalleryとWindows Community Toolkitから実際に動くコード例を検索するもので、対象はWinUIに限られます(WPFやWinFormsは対象外)。コーパスは初回実行時にGitHubから取得してユーザーごとにキャッシュされます。ただし、7日間隔のキャッシュ更新や --refresh を指定した強制更新でもネットワーク接続が必要です。--source core を指定すると組み込みパターンのみを検索し、完全にオフラインで動きます。
採用を判断するときの注意点
試す価値は高い一方、本番の配布パイプラインに組み込むかは慎重に判断すべき段階です。
- Public Previewであることが公式に明記されています。READMEは「experimental and in active development」と書いており、フィードバックを募っている状態です。0.x系のためコマンド体系の変更もあり得ます。
- ドキュメントとリリースがずれます。READMEとdocsの
mainブランチは開発中の内容を含み、リリース済みの版には無い機能が載っていることがあります。手順を確認するときは、使っている版のタグを指定してドキュメントを読むのが安全です。 - Windows専用です。macOSやLinuxのCIランナーでは動かないため、クロスプラットフォームのビルドではWindowsランナーを分ける必要があります。
- ストア提出は別サービスの領域です。前述のとおり
winapp storeはmsstoreへの転送であり、Partner Centerの登録・審査は従来どおりです。
まずは既存アプリの検証用exeに winapp create-debug-identity で開発用IDを付け、通知やファイル関連付けが動くかを確認する範囲から始めると、既存のビルド構成を壊さずに評価できます。
よくある質問
winapp CLIはVisual Studioの代わりになりますか?
コードエディタやデバッガーとしての置き換えではありません。Visual StudioやMSBuildに依存せずSDK導入・マニフェスト生成・証明書発行・MSIX化を行うための道具です。エディタはVS Codeでも他の環境でも構わず、VS Code用には専用拡張も提供されています。
winapp packとwinapp packageは違うコマンドですか?
同じコマンドです。コマンド定義上は package が正式名で、pack が別名として登録されています。同様に tool には run-buildtool という別名があります。
開発用証明書を作るコマンドは何ですか?
winapp cert generate です。cert グループにあるのは generate・info・install の3つで、cert create というサブコマンドはv0.6.1の定義に存在しません。
npm版とWinGet版で使える機能は同じですか?
同じではありません。node 配下の4コマンド(アドオン生成、JSバインディング生成、Electronのデバッグ用ID付与と解除)はnpmパッケージ限定で、WinGetで入れたCLIには現れません。それ以外のコマンドは共通です。
CIでUI操作の自動テストを回せますか?
コマンドを選べば回せます。inspect・search・get-value・wait-for・invoke・set-value・screenshot はUIAのパターン経由で動くためロック中のセッションでも使えます。一方 click・touch・pen・send-keys --via send-input などOSレベルの入力を合成する動詞は、ロック解除された対話的デスクトップが必要で、条件を満たさないと no_interactive_desktop エラーで即座に失敗します。