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 dieser Anleitung wird veranschaulicht, wie Sie eine WinUI-App mit einer einzelnen Instanz mit C# und dem Windows App SDK erstellen. Apps mit Einzelinstanz-Modus erlauben nur jeweils eine Instanz der App, die ausgeführt werden kann. WinUI-Apps sind standardmäßig multiinstanziert. Sie ermöglichen es Ihnen, mehrere Instanzen derselben App gleichzeitig zu starten. Es wird auf mehrere Instanzen verwiesen. Sie können jedoch die Einzelinstanzerstellung basierend auf dem Anwendungsfall Ihrer App implementieren. Der Versuch, eine zweite Instanz einer einzelinstanzierten App zu starten, führt nur dazu, dass stattdessen das Hauptfenster der ersten Instanz aktiviert wird. In diesem Tutorial wird gezeigt, wie man eine Einzelinstanzierung in einer WinUI-App implementiert.
In diesem Artikel erfahren Sie, wie Sie:
- Deaktivieren Sie den generierten XAML-Code
Program - Definieren einer benutzerdefinierten
MainMethode für die Umleitung - Testen der Einzelinstanzerstellung nach der App-Bereitstellung
Voraussetzungen
Dieses Lernprogramm verwendet Visual Studio und baut auf der Vorlage für leere WinUI-Apps auf. Wenn Sie neu in der WinUI-Entwicklung sind, können Sie, indem Sie den Anweisungen in Erste Schritte mit WinUI folgen, alles einrichten. Dort installieren Sie Visual Studio, konfigurieren sie für die Entwicklung von Apps mit WinUI, während Sie sicherstellen, dass Sie über die neueste WinUI- und die Windows App SDK verfügen und eine Hello World project erstellen.
Wenn Sie dies getan haben, kehren Sie hierher zurück, um zu erfahren, wie Sie Ihre "Hello World" project in eine einzelinstanzierte App umwandeln.
Hinweis
Diese Anleitung basiert auf dem Blogbeitrag " Erstellen der App zu einer Einzelinstanz (Teil 3)" aus einer Windows-Blogreihe über WinUI. Der Code für diese Artikel ist auf GitHub verfügbar.
Automatisch generierten Programmcode deaktivieren
Wir müssen die Umleitung so früh wie möglich überprüfen, bevor wir Fenster erstellen. Um dies zu tun, müssen wir das Symbol "DISABLE_XAML_GENERATED_MAIN" in der Projektdatei definieren. Führen Sie die folgenden Schritte aus, um den automatisch generierten Programmcode zu deaktivieren:
Klicken Sie im Solution Explorer mit der rechten Maustaste auf den Projektnamen und wählen Sie Projektdatei bearbeiten aus.
Definieren Sie das DISABLE_XAML_GENERATED_MAIN-Symbol . Fügen Sie der Projektdatei das folgende XML-Element hinzu:
<PropertyGroup> <DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants> </PropertyGroup>
Wenn Sie das Symbol DISABLE_XAML_GENERATED_MAIN hinzufügen, wird der automatisch generierte Programmcode für Ihre project deaktiviert.
Definieren Sie eine Programklasse mit einer Main-Methode
Eine angepasste Program.cs Datei muss erstellt werden, anstatt die Standard-Main-Methode auszuführen. Der Code, der der Program-Klasse hinzugefügt wurde, ermöglicht der App die Überprüfung auf Umleitung, was nicht das Standardverhalten von WinUI-Apps ist.
Navigieren Sie zu Solution Explorer, klicken Sie mit der rechten Maustaste auf den Projektnamen, und wählen Sie Add | Class.
Benennen Sie die neue Klasse
Program.cs, und wählen Sie "Hinzufügen" aus.Fügen Sie der Program-Klasse die folgenden Namespaces hinzu, und ersetzen Sie alle vorhandenen Namespaces:
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; using Microsoft.Windows.AppLifecycle;Ersetzen Sie die leere Program-Klasse durch Folgendes:
public class Program { [STAThread] static int Main(string[] args) { WinRT.ComWrappersSupport.InitializeComWrappers(); bool isRedirect = DecideRedirection(); if (!isRedirect) { Application.Start((p) => { var context = new DispatcherQueueSynchronizationContext( DispatcherQueue.GetForCurrentThread()); SynchronizationContext.SetSynchronizationContext(context); _ = new App(); }); } return 0; } }Die Main-Methode bestimmt, ob die App zur ersten Instanz umgeleitet werden soll oder ob eine neue Instanz nach dem Aufruf von 'DecideRedirection', die wir als nächstes definieren werden, gestartet werden soll.
Definieren Sie die DecideRedirection-Methode unter der Main-Methode :
private static bool DecideRedirection() { bool isRedirect = false; AppActivationArguments args = AppInstance.GetCurrent().GetActivatedEventArgs(); ExtendedActivationKind kind = args.Kind; AppInstance keyInstance = AppInstance.FindOrRegisterForKey("MySingleInstanceApp"); if (keyInstance.IsCurrent) { keyInstance.Activated += OnActivated; } else { isRedirect = true; RedirectActivationTo(args, keyInstance); } return isRedirect; }DecideRedirection bestimmt, ob die App durch Registrieren eines eindeutigen Schlüssels registriert wurde, der Ihre App-Instanz darstellt. Basierend auf dem Ergebnis der Schlüsselregistrierung kann ermittelt werden, ob eine aktuelle Instanz der App ausgeführt wird. Nach der Bestimmung entscheidet die Methode, ob die App umgeleitet wird oder den Start der neuen Instanz fortsetzt. Die RedirectActivationTo-Methode wird aufgerufen, wenn die Umleitung erforderlich ist.
Als Nächstes erstellen wir die RedirectActivationTo-Methode unterhalb der DecideRedirection-Methode zusammen mit den erforderlichen DllImport-Anweisungen. Fügen Sie der Program-Klasse den folgenden Code hinzu:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)] private static extern IntPtr CreateEvent( IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName); [DllImport("kernel32.dll")] private static extern bool SetEvent(IntPtr hEvent); [DllImport("ole32.dll")] private static extern uint CoWaitForMultipleObjects( uint dwFlags, uint dwMilliseconds, ulong nHandles, IntPtr[] pHandles, out uint dwIndex); [DllImport("user32.dll")] static extern bool SetForegroundWindow(IntPtr hWnd); private static IntPtr redirectEventHandle = IntPtr.Zero; // Do the redirection on another thread, and use a non-blocking // wait method to wait for the redirection to complete. public static void RedirectActivationTo(AppActivationArguments args, AppInstance keyInstance) { redirectEventHandle = CreateEvent(IntPtr.Zero, true, false, null); Task.Run(() => { keyInstance.RedirectActivationToAsync(args).AsTask().Wait(); SetEvent(redirectEventHandle); }); uint CWMO_DEFAULT = 0; uint INFINITE = 0xFFFFFFFF; _ = CoWaitForMultipleObjects( CWMO_DEFAULT, INFINITE, 1, [redirectEventHandle], out uint handleIndex); // Bring the window to the foreground Process process = Process.GetProcessById((int)keyInstance.ProcessId); SetForegroundWindow(process.MainWindowHandle); }Die RedirectActivationTo-Methode ist für die Umleitung der Aktivierung an die erste Instanz der App verantwortlich. Es erstellt einen Ereignishandle, startet einen neuen Thread, um die Aktivierung umzuleiten, und wartet, bis die Umleitung abgeschlossen ist. Nach Abschluss der Umleitung bringt die Methode das Fenster in den Vordergrund.
Definieren Sie schließlich die Hilfsmethode OnActivated unter der DecideRedirection-Methode :
private static void OnActivated(object sender, AppActivationArguments args) { ExtendedActivationKind kind = args.Kind; }
Testen der Single-Instanzierung durch die Bereitstellung der App
Bis zu diesem Punkt testen wir die App durch Debuggen innerhalb von Visual Studio. Es kann jedoch nur ein Debugger gleichzeitig ausgeführt werden. Diese Einschränkung verhindert, dass wir nicht feststellen können, ob die App nur als eine einzige Instanz ausgeführt wird, da wir das gleiche Projekt nicht zweimal gleichzeitig debuggen können. Für einen genauen Test stellen wir die Anwendung auf unserem lokalen Windows-Client bereit. Nach der Bereitstellung können wir die App wie jede app, die unter Windows installiert ist, über den Desktop starten.
Navigieren Sie zum Projektmappen-Explorer, klicken Sie mit der rechten Maustaste auf den Projektnamen, und wählen Sie Deploy aus.
Öffnen Sie das Startmenü und klicken Sie in das Suchfeld.
Geben Sie den Namen Ihrer App in das Suchfeld ein.
Klicken Sie auf das App-Symbol aus dem Suchergebnis, um Ihre App zu starten.
Hinweis
Wenn Sie im Veröffentlichungsmodus App-Abstürze erleben, gibt es einige bekannte Probleme mit beschnittenen Apps im Windows App SDK. Sie können die Kürzung im project deaktivieren, indem Sie die Eigenschaft PublishTrimmed auf false für alle Buildkonfigurationen in den dateien
.pubxmlIhres project festlegen. Weitere Informationen finden Sie unter dieses Issue auf GitHub.Wiederholen Sie die Schritte 2 bis 4, um dieselbe App erneut zu starten, und überprüfen Sie, ob eine andere Instanz geöffnet wird. Wenn die App als Einzel-Instanz konfiguriert ist, wird die erste Instanz anstatt einer neuen Instanz aktiviert.
Tipp
Optional können Sie der OnActivated-Methode einen Protokollierungscode hinzufügen, um zu überprüfen, ob die vorhandene Instanz aktiviert wurde. Versuchen Sie, Copilot um Hilfe beim Hinzufügen einer ILogger-Implementierung zu Ihrer WinUI-App zu bitten.
Zusammenfassung
Der gesamte hier behandelte Code befindet sich auf GitHub mit Verzweigungen für die verschiedenen Schritte in der ursprünglichen Windows Blogreihe. Im single-instancing Zweig steht Code speziell für diese Vorgehensweise zur Verfügung. Die main Filiale ist die umfassendste. Die anderen Zweige sollen Ihnen zeigen, wie sich die Architektur der App entwickelt hat.
Zugehöriger Inhalt
App-Instanziierung mit der App-Lebenszyklus-API
Windows developer