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.
Erfahren Sie, wie Sie eine UWP-App schreiben, die das Windows Device Portal (WDP) zum Hosten einer Webseite verwendet und Diagnoseinformationen bereitstellt.
Ab Windows 10 Creators Update (Version 1703, Build 15063) können Sie das Geräteportal verwenden, um die Diagnoseschnittstellen Ihrer App zu hosten. In diesem Artikel werden die drei Teile behandelt, die zum Erstellen eines DevicePortalProviders für Ihre App erforderlich sind– das Anwendungspaketmanifest Änderungen, das Einrichten der Verbindung Ihrer App mit dem Device Portal-Dienstund die Behandlung einer eingehenden Anforderung.
Erstellen eines neuen UWP-App-Projekts
Erstellen Sie in Microsoft Visual Studio ein neues UWP-App-Projekt. Wechseln Sie zu Datei > Neues > Projekt und wählen Sie Leere App (Windows Universal) für C#-aus, und klicken Sie dann auf Weiter. Im Dialogfeld Neues Projekt konfigurieren. Nennen Sie das Projekt "DevicePortalProvider", und klicken Sie dann auf Erstellen. Dies wird die Anwendung sein, die den Anwendungsdienst enthält. Möglicherweise müssen Sie Visual Studio aktualisieren oder das neueste Windows SDKinstallieren.
Fügen Sie die devicePortalProvider-Erweiterung zu Ihrem Anwendungspaketmanifest hinzu.
Sie müssen Ihrem package.appxmanifest Datei Code hinzufügen, um Ihre App als Device Portal-Plugin funktionstüchtig zu machen. Fügen Sie zuerst die folgenden Namespacedefinitionen am Anfang der Datei hinzu. Fügen Sie sie auch dem Attribut IgnorableNamespaces hinzu.
<Package
...
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:uap4="http://schemas.microsoft.com/appx/manifest/uap/windows10/4"
IgnorableNamespaces="uap mp rescap uap4">
...
Um zu deklarieren, dass Ihre App ein Geräteportalanbieter ist, müssen Sie einen App-Dienst und eine neue Geräteportalanbietererweiterung erstellen, die sie verwendet. Fügen Sie sowohl die Erweiterung "windows.appService" als auch die Erweiterung "windows.devicePortalProvider" im Extensions-Element unter Applicationhinzu. Stellen Sie sicher, dass die AppServiceName Attribute in jeder Erweiterung übereinstimmen. Dies zeigt dem Device Portal-Dienst an, dass dieser Anwendungsdienst gestartet werden kann, um Anforderungen im Handler-Namensraum zu verarbeiten.
...
<Application
Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="DevicePortalProvider.App">
...
<Extensions>
<uap:Extension Category="windows.appService" EntryPoint="MySampleProvider.SampleProvider">
<uap:AppService Name="com.sampleProvider.wdp" />
</uap:Extension>
<uap4:Extension Category="windows.devicePortalProvider">
<uap4:DevicePortalProvider
DisplayName="My Device Portal Provider Sample App"
AppServiceName="com.sampleProvider.wdp"
HandlerRoute="/MyNamespace/api/" />
</uap4:Extension>
</Extensions>
</Application>
...
Das HandlerRoute-Attribut verweist auf den REST-Namespace, der von Ihrer App beansprucht wird. Alle HTTP-Anforderungen für diesen Namespace (implizit gefolgt von einem Platzhalter), die vom Device Portal-Dienst empfangen werden, werden an Ihre App gesendet, um verarbeitet zu werden. In diesem Fall werden alle erfolgreich authentifizierten HTTP-Anforderungen an <ip_address>/MyNamespace/api/* an Ihre App gesendet. Konflikte zwischen Handlerrouten werden über eine "längste Wins"-Prüfung abgerechnet: Je nachdem, welche Route mehr der Anforderungen entspricht, wird ausgewählt, was bedeutet, dass eine Anforderung an "/MyNamespace/api/foo" mit einem Anbieter mit "/MyNamespace/api" und nicht mit "/MyNamespace" übereinstimmt.
Für diese Funktionalität sind zwei neue Funktionen erforderlich. Sie müssen auch Ihrer Datei "package.appxmanifest" hinzugefügt werden.
...
<Capabilities>
...
<Capability Name="privateNetworkClientServer" />
<rescap:Capability Name="devicePortalProvider" />
</Capabilities>
...
Hinweis
Die Funktion "devicePortalProvider" ist eingeschränkt ("rescap"), was bedeutet, dass Sie eine vorherige Genehmigung aus dem Store erhalten müssen, bevor Ihre App dort veröffentlicht werden kann. Dies verhindert jedoch nicht, dass Sie Ihre App lokal durch Querladen testen. Weitere Informationen zu eingeschränkten Funktionen finden Sie unter App-Funktionsdeklarationen.
Einrichten der Hintergrundaufgabe und WinRT-Komponente
Um die Geräteportalverbindung einzurichten, muss Ihre App eine App-Dienstverbindung vom Device Portal-Dienst mit der Instanz des Geräteportals verbinden, die in Ihrer App ausgeführt wird. Fügen Sie dazu ihrer Anwendung eine neue WinRT-Komponente mit einer Klasse hinzu, die IBackgroundTaskimplementiert.
using Windows.System.Diagnostics.DevicePortal;
using Windows.ApplicationModel.Background;
namespace MySampleProvider {
// Implementing a DevicePortalConnection in a background task
public sealed class SampleProvider : IBackgroundTask {
BackgroundTaskDeferral taskDeferral;
DevicePortalConnection devicePortalConnection;
//...
}
Stellen Sie sicher, dass der Name dem Namespace und dem Klassennamen entspricht, der vom AppService EntryPoint ("MySampleProvider.SampleProvider") eingerichtet wurde. Wenn Sie Ihre erste Anforderung an Ihren Geräteportalanbieter stellen, speichert das Geräteportal die Anforderung zwischen, startet die Hintergrundaufgabe Ihrer App, ruft die Run-Methode auf und übergibt eine IBackgroundTaskInstance. Ihre App verwendet dann diese, um eine DevicePortalConnection Instanz einzurichten.
// Implement background task handler with a DevicePortalConnection
public void Run(IBackgroundTaskInstance taskInstance) {
// Take a deferral to allow the background task to continue executing
this.taskDeferral = taskInstance.GetDeferral();
taskInstance.Canceled += TaskInstance_Canceled;
// Create a DevicePortal client from an AppServiceConnection
var details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
var appServiceConnection = details.AppServiceConnection;
this.devicePortalConnection = DevicePortalConnection.GetForAppServiceConnection(appServiceConnection);
// Add Closed, RequestReceived handlers
devicePortalConnection.Closed += DevicePortalConnection_Closed;
devicePortalConnection.RequestReceived += DevicePortalConnection_RequestReceived;
}
Es gibt zwei Ereignisse, die von der App behandelt werden müssen, um die Anforderungsbehandlungsschleife abzuschließen: Closed, für jedes Mal, wenn der Device Portal-Dienst heruntergefahren wird, und RequestReceived, die eingehende HTTP-Anforderungen anzeigt und die Hauptfunktionalität des Geräteportalanbieters bereitstellt.
Behandeln des RequestReceived-Ereignisses
Das RequestReceived-Ereignis wird einmal für jede HTTP-Anforderung ausgelöst, die auf der angegebenen Handlerroute Ihres Plug-Ins vorgenommen wird. Die Anforderungsbehandlungsschleife für Geräteportalanbieter ist ähnlich wie bei NodeJS Express: Die Anforderungs- und Antwortobjekte werden zusammen mit dem Ereignis bereitgestellt, und der Handler antwortet, indem er das Antwortobjekt ausfüllt. In Device Portal-Anbietern verwenden das RequestReceived--Ereignis und die zugehörigen Handler Windows.Web.HttpRequestMessage und HttpResponseMessage--Objekte.
// Sample RequestReceived echo handler: respond with an HTML page including the query and some additional process information.
private void DevicePortalConnection_RequestReceived(DevicePortalConnection sender, DevicePortalConnectionRequestReceivedEventArgs args)
{
var req = args.RequestMessage;
var res = args.ResponseMessage;
if (req.RequestUri.AbsolutePath.EndsWith("/echo"))
{
// construct an html response message
string con = "<h1>" + req.RequestUri.AbsoluteUri + "</h1><br/>";
var proc = Windows.System.Diagnostics.ProcessDiagnosticInfo.GetForCurrentProcess();
con += String.Format("This process is consuming {0} bytes (Working Set)<br/>", proc.MemoryUsage.GetReport().WorkingSetSizeInBytes);
con += String.Format("The process PID is {0}<br/>", proc.ProcessId);
con += String.Format("The executable filename is {0}", proc.ExecutableFileName);
res.Content = new Windows.Web.HttpStringContent(con);
res.Content.Headers.ContentType = new Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("text/html");
res.StatusCode = Windows.Web.Http.HttpStatusCode.Ok;
}
//...
}
In diesem Beispielanforderungshandler rufen wir zuerst die Anforderungs- und Antwortobjekte aus den Args Parameter ab und erstellen dann eine Zeichenfolge mit der Anforderungs-URL und einige zusätzliche HTML-Formatierungen. Dem Response-Objekt wird dies als HttpStringContent Instanz hinzugefügt. Andere IHttpContent- Klassen, zum Beispiel für "String" und "Buffer," sind ebenfalls zulässig.
Die Antwort wird dann als HTTP-Antwort festgelegt und erhält einen Statuscode 200 (OK). Es sollte im Browser, der den ursprünglichen Aufruf gemacht hat, wie erwartet gerendert werden. Beachten Sie, dass, wenn der RequestReceived- Ereignishandler zurückkehrt, die Antwortnachricht automatisch an den Benutzer-Agent zurückgegeben wird: Es ist keine zusätzliche "send"-Methode erforderlich.
Bereitstellen statischer Inhalte
Statische Inhalte können direkt aus einem Ordner innerhalb des Pakets bereitgestellt werden, wodurch es sehr einfach ist, Ihrer Anwendung eine Benutzeroberfläche hinzuzufügen. Die einfachste Möglichkeit zum Bereitstellen statischer Inhalte besteht darin, einen Inhaltsordner in Ihrem Projekt zu erstellen, der einer URL zugeordnet werden kann.
Fügen Sie dann einen Routenhandler in Ihrem RequestReceived Ereignishandler hinzu, der statische Inhaltsrouten erkennt und eine Anforderung entsprechend ordnet.
if (req.RequestUri.LocalPath.ToLower().Contains("/www/")) {
var filePath = req.RequestUri.AbsolutePath.Replace('/', '\\').ToLower();
filePath = filePath.Replace("\\backgroundprovider", "")
try {
var fileStream = Windows.ApplicationModel.Package.Current.InstalledLocation.OpenStreamForReadAsync(filePath).GetAwaiter().GetResult();
res.StatusCode = HttpStatusCode.Ok;
res.Content = new HttpStreamContent(fileStream.AsInputStream());
res.Content.Headers.ContentType = new HttpMediaTypeHeaderValue("text/html");
} catch(FileNotFoundException e) {
string con = String.Format("<h1>{0} - not found</h1>\r\n", filePath);
con += "Exception: " + e.ToString();
res.Content = new Windows.Web.Http.HttpStringContent(con);
res.StatusCode = Windows.Web.Http.HttpStatusCode.NotFound;
res.Content.Headers.ContentType = new Windows.Web.Http.Headers.HttpMediaTypeHeaderValue("text/html");
}
}
Stellen Sie sicher, dass alle Dateien im Inhaltsordner als "Inhalt" gekennzeichnet sind und in Visual Studios Eigenschaften-Menü auf "Kopieren, wenn neuer" oder "Immer kopieren" gesetzt werden. Dadurch wird sichergestellt, dass sich die Dateien in Ihrem AppX-Paket befinden, wenn Sie es bereitstellen.
Verwenden bestehender Ressourcen des Geräteportals und APIs
Statische Inhalte, die von einem Geräteportalanbieter bereitgestellt werden, werden an demselben Port wie der zentrale Device Portal-Dienst bereitgestellt. Dies bedeutet, dass Sie auf die vorhandenen JS und CSS im Device Portal mit einfachen <link> und <script> Tags in Ihrem HTML-Code verweisen können. Im Allgemeinen empfehlen wir die Verwendung von rest.js, die alle Kern-REST-APIs des Geräteportals in einem praktischen WebbRest-Objekt umschließt, und die common.css Datei, mit der Sie Ihre Inhalte so gestalten können, dass sie zur restlichen Benutzeroberfläche des Geräteportals passen. Ein Beispiel hierfür finden Sie auf der im Beispiel enthaltenen index.html Seite. Es verwendet rest.js, um den Gerätenamen und ausgeführte Prozesse aus dem Geräteportal abzurufen.
Wichtig ist, dass die Verwendung der HttpPost/DeleteExpect200-Methoden in webbRest automatisch die CSRF-Verarbeitung für Sie übernimmt, wodurch Ihre Webseite zustandsverändernde REST-APIs aufrufen kann.
Hinweis
Die statischen Inhalte, die im Geräteportal enthalten sind, sind nicht mit einer Garantie gegen die Unterbrechung von Änderungen ausgestattet. Obwohl die APIs nicht häufig geändert werden sollen, können sie insbesondere in den Dateien common.js und controls.js geändert werden, die vom Anbieter nicht verwendet werden sollten.
Fehlerbehebung der Verbindung zum Geräteportal
Um Die Hintergrundaufgabe zu debuggen, müssen Sie die Art und Weise ändern, wie Visual Studio Ihren Code ausführt. Führen Sie die folgenden Schritte zum Debuggen einer App-Dienstverbindung aus, um zu prüfen, wie Ihr Anbieter die HTTP-Anforderungen verarbeitet:
- Wählen Sie im Menü "Debuggen" die Option "DevicePortalProvider-Eigenschaften" aus.
- Wählen Sie auf der Registerkarte "Debuggen" im Abschnitt "Startaktion" die Option "Nicht starten, aber meinen Code debuggen, wenn er gestartet wird".
- Legen Sie einen Haltepunkt in Ihrer Handlerfunktion RequestReceived fest.
Hinweis
Stellen Sie sicher, dass die Buildarchitektur exakt mit der Architektur des Ziels übereinstimmt. Wenn Sie einen 64-Bit-PC verwenden, müssen Sie eine Bereitstellung mit einem AMD64-Build durchführen. 4. Drücken Sie F5, um Ihre App bereitzustellen. Deaktivieren Sie das Geräteportal und aktivieren Sie es dann wieder, damit es Ihre App findet (nur erforderlich, wenn Sie Ihr App-Manifest ändern – den Rest der Zeit können Sie einfach erneut bereitstellen und diesen Schritt überspringen). 6. Greifen Sie in Ihrem Browser auf den Namespace des Anbieters zu; der "Breakpoint" (Haltepunkt) sollte erreicht werden.