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.
Hinweis
Die Codebeispiele in diesem Thema sind ausschließlich in C#. Eine App-Beispiel-App in C++/WinRT sowie C# finden Sie im Beispiel " App-Dienste ", oder rufen Sie die Quelle der Beispielprojekte für App-Dienste auf GitHub ab.
Von Bedeutung
Dieses Thema bezieht sich auf die UWP-Apps (Universelle Windows-Plattform), die .NET Native verwenden. Visual Studio 2022 enthält jetzt auch UWP-Projektvorlagen, die .NET 9 verwenden. Für dieses Thema müssen Sie die UWP-Projektvorlagen verwenden, die ".NET Native" in ihren Namen enthalten, z. B. "Leere UWP-App (.NET Native)". Die UWP-Projekte, die .NET 9 verwenden, wurden mit diesem Thema nicht getestet und funktionieren möglicherweise nicht wie erwartet.
App-Dienste sind UWP-Apps, die Dienste für andere UWP-Apps bereitstellen. Sie sind analog zu Webdiensten auf einem Gerät. Ein App-Dienst wird als Hintergrundaufgabe in der Host-App ausgeführt und kann seinen Dienst für andere Apps bereitstellen. Beispielsweise kann ein App-Dienst einen Balkencodescannerdienst bereitstellen, den andere Apps verwenden könnten. Oder eine Enterprise-Suite von Apps verfügt über einen allgemeinen App-Dienst für die Rechtschreibprüfung, der für die anderen Apps in der Suite verfügbar ist. Mit App-Diensten können Sie benutzeroberflächenlose Dienste erstellen, die Apps auf demselben Gerät aufrufen können, und ab Windows 10, Version 1607, auf Remotegeräten.
Ab Windows 10, Version 1607, können Sie App-Dienste erstellen, die im gleichen Prozess wie die Host-App ausgeführt werden. Dieser Artikel konzentriert sich auf das Erstellen und Verwenden eines App-Diensts, der in einem separaten Hintergrundprozess ausgeführt wird. Weitere Informationen zum Ausführen eines App-Diensts im selben Prozess wie der Anbieter finden Sie unter , um einen App-Dienst so zu konvertieren, dass er im selben Prozess wie seine Host-App läuft.
Erstellen eines neuen App-Dienstanbieterprojekts
In dieser Anleitung erstellen wir alles in einer einzigen Lösung der Einfachheit halber.
- Erstellen Sie in Visual Studio 2022 oder höher ein neues UWP-App-Projekt, und nennen Sie es "AppServiceProvider".
- Wählen Sie Datei > Neues > Projekt erstellen...
- Wählen Sie im Dialogfeld " Neues Projekt erstellen " die Option "Leere UWP-App (.NET Native)" aus. Achten Sie darauf, den C#-Projekttyp auszuwählen. Dies ist die App, die den App-Dienst anderen UWP-Apps zur Verfügung stellt.
- Klicken Sie auf Weiter, und benennen Sie das Projekt AppServiceProvider, wählen Sie einen Speicherort dafür aus, und klicken Sie dann auf Erstellen.
- Wenn Sie aufgefordert werden, eine Ziel- auszuwählen und Mindestversion für das Projekt auszuwählen, wählen Sie mindestens 10.0.14393aus. Wenn Sie das neue SupportsMultipleInstances-Attribut verwenden möchten, müssen Sie auf 10.0.15063 (Windows 10 Creators Update) oder höher abzielen.
Fügen Sie eine App-Diensterweiterung zu Package.appxmanifest hinzu
Öffnen Sie im AppServiceProvider Projekt die Datei Package.appxmanifest in einem Text-Editor.
- Klicken Sie im Projektmappen-Explorermit der rechten Maustaste darauf.
- Wählen Sie Öffnen mit.
- Wählen Sie XML-Editor (Text)aus.
Fügen Sie die folgende AppService Erweiterung innerhalb des <Application>-Elements hinzu. In diesem Beispiel wird der com.microsoft.inventory Dienst beworben, was diese App als einen App-Dienstanbieter kennzeichnet. Der eigentliche Dienst wird als Hintergrundaufgabe implementiert. Das App-Dienstprojekt macht den Dienst für andere Apps verfügbar. Es wird empfohlen, einen umgekehrten Domänennamenstil für den Dienstnamen zu verwenden.
Beachten Sie, dass das xmlns:uap4-Namespacepräfix und das Attribut uap4:SupportsMultipleInstances nur gültig sind, wenn Sie Windows SDK Version 10.0.15063 oder höher verwenden. Sie können sie sicher entfernen, wenn Sie auf ältere SDK-Versionen abzielen.
Hinweis
Eine Beispiel-App für einen App-Dienst in C++/WinRT- sowie C# finden Sie in der Beispiel-App für App-Dienst.
<Package
...
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
...
<Applications>
<Application Id="AppServiceProvider.App"
Executable="$targetnametoken$.exe"
EntryPoint="AppServiceProvider.App">
...
<Extensions>
<uap:Extension Category="windows.appService" EntryPoint="MyAppService.Inventory">
<uap3:AppService Name="com.microsoft.inventory" uap4:SupportsMultipleInstances="true"/>
</uap:Extension>
</Extensions>
...
</Application>
</Applications>
Das Category Attribut identifiziert diese Anwendung als App-Dienstanbieter, und das EntryPoint Attribut identifiziert die namespacequalifizierte Klasse, die den Dienst implementiert. Dies wird als Nächstes implementiert.
Das Attribut SupportsMultipleInstances gibt an, dass jedes Mal, wenn der App-Dienst aufgerufen wird, er in einem neuen Prozess ausgeführt werden sollte. Dies ist nicht erforderlich, steht Ihnen aber zur Verfügung, wenn Sie diese Funktionalität benötigen und auf das 10.0.15063 SDK (Windows 10 Creators Update) oder höher abzielen. Sie sollte auch mit dem Namensraum uap4 eingeleitet werden.
Erstellen des App-Diensts
In diesem Abschnitt erstellen wir einen App-Dienst, der als Hintergrundaufgabe ausgeführt wird. Der App-Dienst stellt einen einfachen Bestandsdienst bereit, der es anderen Apps ermöglicht, den Namen und den Preis der Artikel im Bestand abzufragen.
Ein App-Dienst kann als Hintergrundaufgabe implementiert werden. Dadurch kann eine Vordergrundanwendung einen App-Dienst in einer anderen Anwendung aufrufen. Um einen App-Dienst als Hintergrundaufgabe zu erstellen, fügen Sie der Lösung ein neues Windows-Runtime-Komponentenprojekt hinzu (Datei > Neues Projekt hinzufügen >) mit dem Namen MyAppService. Wählen Sie im Dialogfeld " Neues Projekt hinzufügen " die Option "Komponente für Windows-Runtime (.NET Native)" aus.
Fügen Sie im Projekt "AppServiceProvider" einen Projektverweis auf das neue Projekt "MyAppService" hinzu (klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt "AppServiceProvider", wählen Sie >Verweis>Lösung, wählen Sie > und klicken Sie auf OK). Dieser Schritt ist entscheidend, da der App-Service zur Laufzeit keine Verbindung herstellen wird, wenn Sie den Verweis nicht hinzufügen.
Fügen Sie im MyAppService Projekt die folgenden mithilfe von Anweisungen oben in Class1.cshinzu:
using Windows.ApplicationModel.AppService; using Windows.ApplicationModel.Background; using Windows.Foundation.Collections;Benennen Sie Class1.cs in Inventory.csum, und ersetzen Sie den Stubcode für Class1 durch eine neue Hintergrundaufgabenklasse namens Inventory:
public sealed class Inventory : IBackgroundTask { private BackgroundTaskDeferral backgroundTaskDeferral; private AppServiceConnection appServiceconnection; private String[] inventoryItems = new string[] { "Robot vacuum", "Chair" }; private double[] inventoryPrices = new double[] { 129.99, 88.99 }; public void Run(IBackgroundTaskInstance taskInstance) { // Get a deferral so that the service isn't terminated. this.backgroundTaskDeferral = taskInstance.GetDeferral(); // Associate a cancellation handler with the background task. taskInstance.Canceled += OnTaskCanceled; // Retrieve the app service connection and set up a listener for incoming app service requests. var details = taskInstance.TriggerDetails as AppServiceTriggerDetails; appServiceconnection = details.AppServiceConnection; appServiceconnection.RequestReceived += OnRequestReceived; } private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { // This function is called when the app service receives a request. } private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) { if (this.backgroundTaskDeferral != null) { // Complete the service deferral. this.backgroundTaskDeferral.Complete(); } } }In dieser Klasse wird der App-Dienst seine Arbeit erledigen.
Run wird aufgerufen, wenn die Hintergrundaufgabe erstellt wird. Da Hintergrundaufgaben nach Abschluss von Ausführung beendet werden, nimmt der Code eine Aufschiebung vor, damit die Hintergrundaufgabe weiterhin Anfragen bedient. Ein App-Dienst, der als Hintergrundaufgabe implementiert wird, bleibt etwa 30 Sekunden aktiv, nachdem er einen Anruf empfängt, es sei denn, er wird innerhalb dieses Zeitfensters erneut aufgerufen oder eine Verzögerung wird beendet. Wenn der App-Dienst im gleichen Prozess wie der Aufrufer implementiert wird, ist die Lebensdauer des App-Diensts an die Lebensdauer des Aufrufers gebunden.
Die Lebensdauer des App-Diensts hängt vom Aufrufer ab:
- Wenn sich der Aufrufer im Vordergrund befindet, entspricht die Lebensdauer des App-Diensts dem Aufrufer.
- Wenn sich der Aufrufer im Hintergrund befindet, wird der App-Dienst 30 Sekunden lang ausgeführt. Ein Aufschub bietet einmalig zusätzlich 5 Sekunden.
OnTaskCanceled wird aufgerufen, wenn die Aufgabe abgebrochen wird. Die Aufgabe wird abgebrochen, wenn die Client-App die AppServiceConnectionverwirft, die Client-App angehalten wird, das Betriebssystem heruntergefahren oder in den Ruhezustand wechselt oder das Betriebssystem keine Ressourcen mehr hat, um die Aufgabe auszuführen.
Schreibe den Code für den App-Service
OnRequestReceived ist der Ort, an dem der Code für den App-Dienst abgelegt wird. Ersetzen Sie den Stub OnRequestReceived in MyAppService's Inventory.cs durch den Code aus diesem Beispiel. Dieser Code ruft einen Index für ein Bestandselement ab und übergibt ihn zusammen mit einer Befehlszeichenfolge an den Dienst, um den Namen und den Preis des angegebenen Bestandselements abzurufen. Fügen Sie für Ihre eigenen Projekte Code zur Fehlerbehandlung hinzu.
private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
// Get a deferral because we use an awaitable API below to respond to the message
// and we don't want this call to get canceled while we are waiting.
var messageDeferral = args.GetDeferral();
ValueSet message = args.Request.Message;
ValueSet returnData = new ValueSet();
string command = message["Command"] as string;
int? inventoryIndex = message["ID"] as int?;
if (inventoryIndex.HasValue &&
inventoryIndex.Value >= 0 &&
inventoryIndex.Value < inventoryItems.GetLength(0))
{
switch (command)
{
case "Price":
{
returnData.Add("Result", inventoryPrices[inventoryIndex.Value]);
returnData.Add("Status", "OK");
break;
}
case "Item":
{
returnData.Add("Result", inventoryItems[inventoryIndex.Value]);
returnData.Add("Status", "OK");
break;
}
default:
{
returnData.Add("Status", "Fail: unknown command");
break;
}
}
}
else
{
returnData.Add("Status", "Fail: Index out of range");
}
try
{
// Return the data to the caller.
await args.Request.SendResponseAsync(returnData);
}
catch (Exception e)
{
// Your exception handling code here.
}
finally
{
// Complete the deferral so that the platform knows that we're done responding to the app service call.
// Note for error handling: this must be called even if SendResponseAsync() throws an exception.
messageDeferral.Complete();
}
}
Beachten Sie, dass OnRequestReceivedasynchron ist, da wir in diesem Beispiel einen wartbaren Methodenaufruf zu SendResponseAsync vornehmen.
Es wird eine Verzögerung ausgeführt, damit der Dienst asynchronen Methoden im OnRequestReceived Handler verwenden kann. Dadurch wird sichergestellt, dass der Aufruf von OnRequestReceived erst abgeschlossen wird, wenn die Verarbeitung der Nachricht abgeschlossen ist. SendResponseAsync sendet das Ergebnis an den Aufrufer. SendResponseAsync signalisiert nicht den Abschluss des Anrufs. Es ist der Abschluss des Aufschubs, der anzeigt, dass OnRequestReceived abgeschlossen wurde, und an SendMessageAsync signalisiert. Der Aufruf von SendResponseAsync wird in einen Try/Finally-Block eingeschlossen, da Sie den Aufschub abschließen müssen, auch wenn SendResponseAsync eine Ausnahme auslöst.
App-Dienste verwenden ValueSet- Objekte, um Informationen auszutauschen. Die Größe der Daten, die Sie übergeben können, ist nur durch Systemressourcen begrenzt. Es gibt keine vordefinierten Schlüssel, die Sie in Ihrem ValueSetverwenden können. Sie müssen bestimmen, welche Schlüsselwerte Sie verwenden, um das Protokoll für Ihren App-Dienst zu definieren. Der Aufrufer muss unter Berücksichtigung dieses Protokolls erstellt werden. In diesem Beispiel haben wir einen Schlüssel namens Command ausgewählt, der einen Wert aufweist, der angibt, ob der App-Dienst den Namen des Bestandselements oder dessen Preis angeben soll. Der Index des Bestandsnamens wird unter dem Schlüssel ID gespeichert. Der Rückgabewert wird unter dem Result Schlüssel gespeichert.
Eine AppServiceClosedStatus- Enumeration wird an den Aufrufer zurückgegeben, um anzugeben, ob der Aufruf des App-Diensts erfolgreich war oder fehlgeschlagen ist. Ein Beispiel dafür, wie der Aufruf des App-Diensts fehlschlägt, ist, wenn das Betriebssystem den Dienstendpunkt abbricht, da seine Ressourcen überschritten wurden. Sie können zusätzliche Fehlerinformationen über das ValueSetzurückgeben. In diesem Beispiel verwenden wir einen Schlüssel namens Status, um detailliertere Fehlerinformationen an den Aufrufer zurückzugeben.
Der Aufruf von SendResponseAsync gibt das ValueSet an den Aufrufenden zurück.
Service-App starten und Paketfamiliennamen abrufen
Der App-Dienstanbieter muss bereitgestellt werden, bevor Sie ihn von einem Client aufrufen können. Sie können es deployen, indem Sie in Visual Studio Build > Deploy Solution auswählen.
Außerdem benötigen Sie den Paketfamiliennamen des App-Diensteanbieters, um es aufzurufen. Sie können dies mit den folgenden Schritten abrufen:
- Öffnen Sie die Datei "Package.appxmanifest" des AppServiceProvider-Projekts in der Designeransicht (doppelklicken Sie im Projektmappen-Explorer darauf).
- Wählen Sie die Registerkarte Verpackung aus, kopieren Sie den Wert neben Paketfamiliennamen, und fügen Sie ihn an einem Ort wie Notepad für den nächsten Schritt ein.
Schreiben eines Clients zum Aufrufen des App-Diensts
In diesem Abschnitt erstellen wir eine Client-App, die den soeben erstellten App-Dienst aufruft. Die Client-App ist eine einfache UWP-App mit einem Textfeld und einer Schaltfläche. Wenn der Benutzer einen Index in das Textfeld eingibt und auf die Schaltfläche klickt, ruft die App den App-Dienst auf, um den Namen und den Preis des Bestandselements in diesem Index abzurufen.
Fügen Sie der Projektmappe ein neues leeres Windows Universal-App-Projekt mit >hinzufügen >. Wählen Sie im Dialogfeld " Neues Projekt hinzufügen " UWP Blank App (.NET Native) aus, und nennen Sie sie "ClientApp".
Fügen Sie im ClientApp Projekt die folgenden mithilfe Anweisung am Anfang MainPage.xaml.cshinzu:
using Windows.ApplicationModel.AppService;Ändern Sie das Raster auf der Hauptseite in ein StackPanel,sodass wir ein Textfeld und eine Schaltfläche hinzufügen können.
Fügen Sie ein TextBox-Element mit dem Namen "textBox" und eine Schaltfläche zu "MainPage.xaml" hinzu.
Fügen Sie eine Schaltfläche mit einem Klickereignishandler namens button_Click und text für den Inhalt hinzu, z. B. "Click Me".
Fügen Sie das asynchrone Schlüsselwort zur Signatur des Schaltflächenhandlers in MainPage.xaml.cs hinzu.
Ersetzen Sie den Stub ihres Schaltflächenklickhandlers durch den folgenden Code. Achten Sie darauf, die
inventoryServiceFelddeklaration in die Klasse einzuschließen.private AppServiceConnection inventoryService; private async void button_Click(object sender, RoutedEventArgs e) { // Add the connection. if (this.inventoryService == null) { this.inventoryService = new AppServiceConnection(); // Here, we use the app service name defined in the app service // provider's Package.appxmanifest file in the <Extension> section. this.inventoryService.AppServiceName = "com.microsoft.inventory"; // Use Windows.ApplicationModel.Package.Current.Id.FamilyName // within the app service provider to get this value. this.inventoryService.PackageFamilyName = "Replace with the package family name"; var status = await this.inventoryService.OpenAsync(); if (status != AppServiceConnectionStatus.Success) { textBox.Text= "Failed to connect"; this.inventoryService = null; return; } } // Call the service. int idx = int.Parse(textBox.Text); var message = new ValueSet(); message.Add("Command", "Item"); message.Add("ID", idx); AppServiceResponse response = await this.inventoryService.SendMessageAsync(message); string result = ""; if (response.Status == AppServiceResponseStatus.Success) { // Get the data that the service sent to us. if (response.Message["Status"] as string == "OK") { result = response.Message["Result"] as string; } } message.Clear(); message.Add("Command", "Price"); message.Add("ID", idx); response = await this.inventoryService.SendMessageAsync(message); if (response.Status == AppServiceResponseStatus.Success) { // Get the data that the service sent to us. if (response.Message["Status"] as string == "OK") { result += " : Price = " + response.Message["Result"] as string; } } textBox.Text = result; }Ersetzen Sie den Paketfamiliennamen in der Zeile
this.inventoryService.PackageFamilyName = "Replace with the package family name";durch den Paketfamiliennamen des AppServiceProvider- Projekts, das Sie oben in Bereitstellen der Dienst-App abgerufen haben, und rufen Sie den Paketfamiliennamenab.Hinweis
Stellen Sie sicher, dass Sie das Zeichenfolgenliteral einfügen, anstatt es in einer Variable zu speichern. Es funktioniert nicht, wenn Sie eine Variable verwenden.
Der Code stellt zunächst eine Verbindung mit dem App-Dienst her. Die Verbindung bleibt geöffnet, bis Sie
this.inventoryServiceentsorgen. Der Name des App-Dienstes muss demAppService-Attribut desName-Elements entsprechen, das Sie der AppServiceProvider--Projekt-Package.appxmanifest--Datei hinzugefügt haben. In diesem Beispiel ist es<uap3:AppService Name="com.microsoft.inventory"/>.Ein ValueSet- namens
messagewird erstellt, um den Befehl anzugeben, den wir an den App-Service senden möchten. Der Beispiel-App-Dienst erwartet einen Befehl, der angibt, welche von zwei Aktionen ausgeführt werden sollen. Wir rufen den Index aus dem Textfeld in der Client-App ab und rufen dann den Dienst mit dem BefehlItemauf, um die Beschreibung des Elements abzurufen. Anschließend führen wir den Aufruf mit dem BefehlPriceaus, um den Preis des Artikels abzurufen. Der Schaltflächentext wird auf das Ergebnis festgelegt.Da AppServiceResponseStatus nur angibt, ob das Betriebssystem den Aufruf mit dem App-Dienst verbinden konnte, überprüfen wir den
StatusSchlüssel im ValueSet- wir vom App-Dienst erhalten, um sicherzustellen, dass er die Anforderung erfüllen konnte.Legen Sie das ClientApp- Projekt als Startprojekt fest (klicken Sie mit der rechten Maustaste im Solution Explorer>Set as StartUp Project), und starten Sie die Projektmappe. Geben Sie die Zahl 1 in das Textfeld ein, und klicken Sie auf die Schaltfläche. Sie sollten "Stuhl : Preis = 88,99" vom Dienst zurückerhalten.
Beheben häufiger Probleme
Wenn der App-Service-Aufruf fehlschlägt, überprüfen Sie Folgendes im ClientApp-Projekt:
- Stellen Sie sicher, dass der Paketfamilienname, der der Bestandsdienstverbindung zugewiesen ist, dem Paketfamiliennamen der AppServiceProvider--App entspricht. Sehen Sie sich die Zeile in button_Click mit
this.inventoryService.PackageFamilyName = "...";an. - Stellen Sie in button_Clicksicher, dass der Name des App-Diensts, der der Bestandsdienstverbindung zugewiesen ist, mit dem App-Dienstnamen im AppServiceProviderPackage.appxmanifest Datei übereinstimmt. Siehe:
this.inventoryService.AppServiceName = "com.microsoft.inventory";. - Stellen Sie sicher, dass die AppServiceProvider App bereitgestellt wurde. (Klicken Sie im Projektmappen-Explorermit der rechten Maustaste auf die Lösung, und wählen Sie Lösung bereitstellen).
Debuggen des App-Diensts
Zum Debuggen des App-Diensts müssen Sie die Lösung so einrichten, dass der App-Dienstanbieter bereitgestellt wird und der App-Dienst von der Client-App aufgerufen werden kann. Folgen Sie diesen Schritten:
- Stellen Sie sicher, dass die Lösung vor dem Debuggen bereitgestellt wird, da die App des App-Dienstanbieters bereitgestellt werden muss, bevor der Dienst aufgerufen werden kann. (In Visual Studio Erstellen > Lösung bereitstellen).
- Klicken Sie im Projektmappen-Explorermit der rechten Maustaste auf das Projekt AppServiceProvider und wählen Sie Eigenschaftenaus. Ändern Sie auf der Registerkarte Debuggen die Einstellung Startaktion zu "Nicht starten, sondern meinen Code debuggen, wenn er gestartet wird". (Hinweis: Wenn Sie C++ verwenden, um Ihren App-Dienstanbieter zu implementieren, ändern Sie im Tab DebuggenAnwendung starten auf Nein).
- Legen Sie im projekt MyAppService in der datei Inventory.cs einen Haltepunkt in OnRequestReceivedfest.
- Legen Sie das AppServiceProvider- Projekt als Startprojekt fest, und drücken Sie F5.
- Starten Sie ClientApp über das Startmenü (nicht aus Visual Studio).
- Geben Sie die Zahl 1 in das Textfeld ein, und drücken Sie die Schaltfläche. Der Debugger wird beim Aufrufen des App-Dienstes am Haltepunkt in Ihrem App-Dienst stoppen.
Debuggen des Clients
Um die Client-App zu debuggen, die den App-Dienst aufruft, müssen Sie den Debugger an den Client-App-Prozess anfügen. Folgen Sie diesen Schritten:
- Befolgen Sie die Anweisungen im vorherigen Schritt, um den Client zu debuggen, der den App-Dienst aufruft.
- Starten Sie ClientApp aus dem Startmenü.
- Fügen Sie den Debugger an den ClientApp.exe Prozess an (nicht den ApplicationFrameHost.exe Prozess). (Wählen Sie in Visual Studio Debug > An Prozess anhängen....)
- Legen Sie im Projekt ClientApp einen Haltepunkt in Button_Clickfest.
- Die Haltepunkte sowohl im Client als auch im App-Dienst werden nun erreicht, wenn Sie die Zahl 1 in das Textfeld ClientApp eingeben und auf die Schaltfläche klicken.
Allgemeine Problembehandlung beim App-Dienst
Wenn nach dem Versuch, eine Verbindung mit einem App-Service herzustellen, ein AppUnavailable Status auftritt, überprüfen Sie Folgendes:
- Stellen Sie sicher, dass das App-Dienstanbieterprojekt und das App-Dienstprojekt bereitgestellt sind. Beide müssen bereitgestellt werden, bevor der Client ausgeführt wird, andernfalls kann der Client keine Verbindung herstellen. Sie können mithilfe von Build>Deploy Solutionaus Visual Studio veröffentlichen.
- Stellen Sie im Projektmappen-Explorersicher, dass ihr App-Dienstanbieterprojekt über einen Projekt-zu-Projektverweis auf das Projekt verfügt, das den App-Dienst implementiert.
- Stellen Sie sicher, dass der
<Extensions>Eintrag und seine untergeordneten Elemente der 'Package.appxmanifest' Datei hinzugefügt wurden, die dem App-Dienstanbieterprojekt gehört, wie oben unter 'Hinzufügen einer App-Diensterweiterung zu "Package.appxmanifest"'. - Stellen Sie sicher, dass die AppServiceConnection.AppServiceName-Zeichenfolge in Ihrem Client, der den App-Dienstanbieter aufruft, dem im
<uap3:AppService Name="..." />-Datei des App-Dienstanbieterprojekts angegebenen entspricht. - Stellen Sie sicher, dass die AppServiceConnection.PackageFamilyName dem Paketfamiliennamen der App-Dienstanbieterkomponente entspricht, wie oben unter Hinzufügen einer App-Diensterweiterung zu Package.appxmanifest angegeben.
- Für out-of-proc-App-Dienste wie den in diesem Beispiel genannten, stellen Sie sicher, dass der im
EntryPoint-Element Ihres App-Dienstanbieterprojekts spezifizierte<uap:Extension ...>in der Package.appxmanifest-Datei mit dem Namespace und dem Klassennamen der öffentlichen Klasse übereinstimmt, die in Ihrem App-Dienstprojekt IBackgroundTask implementiert.
Behandeln von Problemen beim Debuggen
Wenn der Debugger nicht an Haltepunkten in Ihren App-Dienstanbieter- oder App-Dienstprojekten stoppt, überprüfen Sie bitte Folgendes:
- Stellen Sie sicher, dass das App-Dienstanbieterprojekt und das App-Dienstprojekt bereitgestellt sind. Beide müssen bereitgestellt werden, bevor der Client ausgeführt wird. Sie können sie aus Visual Studio bereitstellen, indem Sie Build>Deploy Solutionverwenden.
- Stellen Sie sicher, dass das Projekt, das Sie debuggen möchten, als Startprojekt festgelegt ist und dass die Debugeigenschaften für dieses Projekt so festgelegt sind, dass das Projekt nicht ausgeführt wird, wenn F5- gedrückt wird. Klicken Sie mit der rechten Maustaste auf das Projekt, klicken Sie dann auf Eigenschaftenund Debuggen (oder Debuggen in C++). Ändern Sie in C# die Startaktion in Nicht starten, sondern debuggen Sie meinen Code, wenn erstartet. Legen Sie in C++ Launch Application auf Nofest.
Bemerkungen
Dieses Beispiel enthält eine Einführung in das Erstellen eines App-Diensts, der als Hintergrundaufgabe ausgeführt und von einer anderen App aufgerufen wird. Die wichtigsten Punkte, die Sie beachten müssen, sind:
- Erstellen Sie eine Hintergrundaufgabe zum Hosten des App-Diensts.
- Fügen Sie die Erweiterung
windows.appServicezur Datei "Package.appxmanifest" des App-Dienstanbieters hinzu. - Rufen Sie den Paketfamiliennamen des App-Dienstanbieters ab, damit wir von der Client-App aus eine Verbindung damit herstellen können.
- Fügen Sie einen Projekt-zu-Projektverweis vom App-Serviceanbieterprojekt zum App-Dienstprojekt hinzu.
- Verwenden Sie Windows.ApplicationModel.AppService.AppServiceConnection, um den Dienst aufzurufen.
Vollständiger Code für MyAppService
Im Folgenden sehen Sie den vollständigen Code für das MyAppService-Projekt , der den App-Dienst als Hintergrundaufgabe implementiert. Dieser Code sollte in der Inventory.cs Datei des MyAppService-Projekts platziert werden.
using System;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.Foundation.Collections;
namespace MyAppService
{
public sealed class Inventory : IBackgroundTask
{
private BackgroundTaskDeferral backgroundTaskDeferral;
private AppServiceConnection appServiceconnection;
private String[] inventoryItems = new string[] { "Robot vacuum", "Chair" };
private double[] inventoryPrices = new double[] { 129.99, 88.99 };
public void Run(IBackgroundTaskInstance taskInstance)
{
// Get a deferral so that the service isn't terminated.
this.backgroundTaskDeferral = taskInstance.GetDeferral();
// Associate a cancellation handler with the background task.
taskInstance.Canceled += OnTaskCanceled;
// Retrieve the app service connection and set up a listener for incoming app service requests.
var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
appServiceconnection = details.AppServiceConnection;
appServiceconnection.RequestReceived += OnRequestReceived;
}
private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
// Get a deferral because we use an awaitable API below to respond to the message
// and we don't want this call to get canceled while we are waiting.
var messageDeferral = args.GetDeferral();
ValueSet message = args.Request.Message;
ValueSet returnData = new ValueSet();
string command = message["Command"] as string;
int? inventoryIndex = message["ID"] as int?;
if (inventoryIndex.HasValue &&
inventoryIndex.Value >= 0 &&
inventoryIndex.Value < inventoryItems.GetLength(0))
{
switch (command)
{
case "Price":
{
returnData.Add("Result", inventoryPrices[inventoryIndex.Value]);
returnData.Add("Status", "OK");
break;
}
case "Item":
{
returnData.Add("Result", inventoryItems[inventoryIndex.Value]);
returnData.Add("Status", "OK");
break;
}
default:
{
returnData.Add("Status", "Fail: unknown command");
break;
}
}
}
else
{
returnData.Add("Status", "Fail: Index out of range");
}
// Return the data to the caller.
await args.Request.SendResponseAsync(returnData);
// Complete the deferral so that the platform knows that we're done responding to the app service call.
// Note for error handling: this must be called even if SendResponseAsync() throws an exception.
messageDeferral.Complete();
}
private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
if (this.backgroundTaskDeferral != null)
{
// Complete the service deferral.
this.backgroundTaskDeferral.Complete();
}
}
}
}