このガイドでは、Flutter アプリケーションで winapp CLI を使用してパッケージ ID を追加し、アプリを MSIX としてパッケージ化する方法について説明します。
パッケージ ID は、Windows app モデルの主要な概念です。 これにより、アプリケーションで特定の Windows API (通知、セキュリティ、AI API など) をaccessしたり、クリーン インストール/アンインストール エクスペリエンスを使用したりできます。
[前提条件]
Flutter SDK: 公式ガイドに従って Flutter をインストールします。
winapp CLI: winget を使用して
winappCLI をインストールします。winget install Microsoft.winappcli --source winget
1. 新しい Flutter アプリを作成する
Flutter の公式ドキュメントのガイドに従って、新しいアプリケーションを作成して実行します。
2. ID を確認するようにコードを更新する
ffi パッケージを追加します。
flutter pub add ffi
lib/main.dartの内容を、Dart FFI 経由の Windows GetCurrentPackageFamilyName API を使用してパッケージ ID をチェックする次のコードに置き換えます。
import 'dart:ffi';
import 'dart:io' show Platform;
import 'package:ffi/ffi.dart';
import 'package:flutter/material.dart';
String? getPackageFamilyName() {
if (!Platform.isWindows) return null;
final kernel32 = DynamicLibrary.open('kernel32.dll');
final getCurrentPackageFamilyName = kernel32.lookupFunction<
Int32 Function(Pointer<Uint32>, Pointer<Uint16>),
int Function(
Pointer<Uint32>, Pointer<Uint16>)>('GetCurrentPackageFamilyName');
final length = calloc<Uint32>();
try {
final result =
getCurrentPackageFamilyName(length, Pointer<Uint16>.fromAddress(0));
if (result != 122) return null; // ERROR_INSUFFICIENT_BUFFER = 122
final namePtr = calloc<Uint16>(length.value);
try {
final result2 = getCurrentPackageFamilyName(length, namePtr);
if (result2 == 0) {
return namePtr.cast<Utf16>().toDartString();
}
return null;
} finally {
calloc.free(namePtr);
}
} finally {
calloc.free(length);
}
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
late final String? _packageFamilyName;
@override
void initState() {
super.initState();
_packageFamilyName = getPackageFamilyName();
}
void _incrementCounter() {
setState(() { _counter++; });
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.only(bottom: 24),
decoration: BoxDecoration(
color: _packageFamilyName != null
? Colors.green.shade50
: Colors.orange.shade50,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: _packageFamilyName != null
? Colors.green
: Colors.orange,
),
),
child: Text(
_packageFamilyName != null
? 'Package Family Name:\n$_packageFamilyName'
: 'Not packaged',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyLarge,
),
),
const Text('You have pushed the button this many times:'),
Text('$_counter',
style: Theme.of(context).textTheme.headlineMedium),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
3. ID なしで実行する
アプリをビルドして実行します。
flutter build windows
.\build\windows\x64\runner\Release\flutter_app.exe
オレンジ色の "パッケージ化されていない" インジケーターが表示されたアプリが表示されます。
4. winapp CLI を使用してprojectを初期化する
winapp init
プロンプトが表示されたら、次を実行します。
- パッケージ名: Enter キーを押して既定値をそのまま使用します
- Publisher名: Enter キーを押して既定値をそのまま使用するか、名前を入力します
- バージョン: Enter キーを押して 1.0.0.0 を受け入れる
- エントリ ポイント: Enter キーを押して既定値 (flutter_app.exe) をそのまま使用します。
- Setup SDK: Windows App SDKをダウンロードして C++ ヘッダーを生成するには、"Stable SDK" を選択します
5. ID を使用したデバッグ
アプリをビルドします。
flutter build windowsデバッグ ID を適用します。
winapp create-debug-identity .\build\windows\x64\runner\Release\flutter_app.exe実行可能ファイルを実行します。
.\build\windows\x64\runner\Release\flutter_app.exe
パッケージ ファミリ名を示す緑色のインジケーターが表示されたアプリが表示されます。
注
flutter cleanの実行または再構築後、実行可能ファイルが置き換えられるため、create-debug-identityを再実行する必要があります。
6. MSIX を使用したパッケージ化
リリース用のビルド:
flutter build windowsパッケージ ディレクトリを準備します。
mkdir dist copy .\build\windows\x64\runner\Release\* .\dist\ -Recurse開発証明書を生成します。
winapp cert generate --if-exists skipパッケージと署名:
winapp pack .\dist --cert .\devcert.pfx証明書をインストールします (管理者として実行)。
winapp cert install .\devcert.pfxパッケージをインストールします。
Add-AppxPackage .\flutter-app.msix
ヒント
- Microsoft Store は MSIX に署名します。提出前に署名する必要はありません。
- Azure信頼された署名は、CI/CD pipelinesの証明書を安全に管理するための優れた方法です。
関連トピック
Windows developer