Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Leitfaden wird veranschaulicht, wie Sie die winapp CLI mit einer Flutter-Anwendung verwenden, um die Paketidentität hinzuzufügen und Ihre App als MSIX zu verpacken.
Die Paketidentität ist ein Kernkonzept im Windows app-Modell. Sie ermöglicht Ihrer Anwendung den Zugriff auf bestimmte Windows-APIs (z. B. Benachrichtigungen, Sicherheit, KI-APIs usw.), eine einfache Installation/Deinstallation und vieles mehr.
Voraussetzungen
Flutter SDK: Installieren Sie Flutter nach dem offiziellen Leitfaden.
winapp CLI: Installieren Sie die
winappCLI über winget:winget install Microsoft.winappcli --source winget
1. Erstellen einer neuen Flutter-App
Folgen Sie dem Leitfaden in den offiziellen Flutter-Dokumenten, um eine neue Anwendung zu erstellen und auszuführen.
2. Aktualisieren von Code zum Überprüfen der Identität
Fügen Sie das ffi -Paket hinzu:
flutter pub add ffi
Ersetzen Sie den Inhalt lib/main.dart durch den folgenden Code, der mithilfe der Windows-API GetCurrentPackageFamilyName über Dart FFI nach Paketidentität sucht:
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. Ohne Identität ausführen
Erstellen und Ausführen der App:
flutter build windows
.\build\windows\x64\runner\Release\flutter_app.exe
Die App sollte mit einem orangefarbenen Indikator "Nicht verpackt" angezeigt werden.
4. Initialisiere das Projekt mit winapp CLI
winapp init
Wenn Sie dazu aufgefordert werden:
- Paketname: Drücken Sie die EINGABETASTE, um die Standardeinstellung zu akzeptieren.
- Publisher Name: Drücken Sie die EINGABETASTE, um die Standardeinstellung zu akzeptieren oder Ihren Namen einzugeben.
- Version: Drücken Sie die EINGABETASTE, um 1.0.0.0 zu akzeptieren.
- Einstiegspunkt: Drücken Sie die EINGABETASTE, um die Standardeinstellung zu übernehmen (flutter_app.exe)
- Setup-SDKs: Wählen Sie "Stable SDKs" aus, um Windows App SDK herunterzuladen und C++-Header zu generieren.
5. Debuggen mit Identität
Erstellen Sie die App:
flutter build windowsDebugidentität anwenden:
winapp create-debug-identity .\build\windows\x64\runner\Release\flutter_app.exeFühren Sie die ausführbare Datei aus:
.\build\windows\x64\runner\Release\flutter_app.exe
Die App sollte mit einem grünen Indikator angezeigt werden, der den Paket-Familiennamen zeigt.
Hinweis
Nach dem Ausführen von flutter clean oder der Neukompilierung müssen Sie create-debug-identity erneut ausführen, da die ausführbare Datei ersetzt wird.
6. Paket mit MSIX
Build für Release:
flutter build windowsVorbereiten des Paketverzeichnisses:
mkdir dist copy .\build\windows\x64\runner\Release\* .\dist\ -RecurseGenerieren eines Entwicklungszertifikats:
winapp cert generate --if-exists skipPacken und Signieren:
winapp pack .\dist --cert .\devcert.pfxInstallieren Sie das Zertifikat (als Administrator ausführen):
winapp cert install .\devcert.pfxInstallieren Sie das Paket:
Add-AppxPackage .\flutter-app.msix
Tipp
- Der Microsoft Store signiert das MSIX für Sie, sodass Sie es nicht vor der Übermittlung signieren müssen.
- Azure Trusted Signing ist eine hervorragende Möglichkeit, Zertifikate für CI/CD-pipelines sicher zu verwalten.
Zugehörige Themen
Windows developer