Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Scopri come scrivere un'app UWP che usa Windows Device Portal (WDP) per ospitare una pagina Web e fornire informazioni di diagnostica.
A partire da Windows 10 Creators Update (versione 1703, build 15063), puoi usare Device Portal per ospitare le interfacce di diagnostica dell'app. Questo articolo illustra i tre componenti necessari per creare un DevicePortalProvider per l'app: le modifiche al manifesto del pacchetto dell'applicazione , la configurazione della connessione dell'app al servizio Device Portale la gestione di una richiesta in ingresso.
Creare un nuovo progetto di app UWP
In Microsoft Visual Studio creare un nuovo progetto di app UWP. Passare a File > Nuovo progetto > e selezionare App vuota (Windows Universale) per C#e quindi fare clic su Avanti. Nella finestra di dialogo Configura il nuovo progetto. Denominare il progetto "DevicePortalProvider" e quindi fare clic su Crea. Questa sarà l'app che contiene il servizio dell'app. Potrebbe essere necessario aggiornare Visual Studio o installare la versione più recente di Windows SDK.
Aggiungi l'estensione devicePortalProvider al manifesto del pacchetto dell'applicazione
Dovrai aggiungere codice al file package.appxmanifest per rendere l'app funzionante come plug-in Device Portal. Innanzitutto, aggiungi le seguenti definizioni dello spazio dei nomi all'inizio del file. Aggiungerli anche all'attributo IgnorableNamespaces
.
<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">
...
Per dichiarare che la tua app è un Device Portal Provider, è necessario creare un servizio app e una nuova estensione per il Device Portal Provider che lo utilizza. Aggiungere sia l'estensione windows.appService che l'estensione windows.devicePortalProvider nell'elemento Extensions
in Application
. Assicurati che gli attributi AppServiceName
corrispondano in ciascuna estensione. Indica al servizio Device Portal che questo servizio app può essere lanciato per gestire le richieste nel namespace del gestore.
...
<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>
...
L'attributo HandlerRoute
fa riferimento allo spazio dei nomi REST richiesto dall'app. Tutte le richieste HTTP in tale spazio dei nomi (seguite in modo implicito da un carattere jolly) ricevute dal servizio Portale dei dispositivi verranno inviate alla tua app per essere gestite. In questo caso, qualsiasi richiesta HTTP autenticata correttamente da <ip_address>/MyNamespace/api/*
verrà inviata all'app. I conflitti tra le route del gestore vengono risolti tramite un controllo "wins più lungo": qualsiasi route corrisponda a più richieste è selezionata, ovvero una richiesta a "/MyNamespace/api/foo" corrisponderà a un provider con "/MyNamespace/api" anziché con "/MyNamespace".
Per questa funzionalità sono necessarie due nuove funzionalità. devono anche essere aggiunti al file package.appxmanifest.
...
<Capabilities>
...
<Capability Name="privateNetworkClientServer" />
<rescap:Capability Name="devicePortalProvider" />
</Capabilities>
...
Annotazioni
La funzionalità "devicePortalProvider" è limitata ("rescap"), il che significa che devi ottenere previa approvazione da parte dello Store prima che la tua app possa essere pubblicata lì. Tuttavia, ciò non impedisce di testare l'app in locale tramite sideloading. Per altre informazioni sulle funzionalità con restrizioni, vedere Dichiarazioni di funzionalità delle app.
Configurare l'attività in background e il componente WinRT
Per configurare la connessione a Device Portal, l'app deve configurare una connessione al servizio app dal servizio Device Portal con l'istanza di Device Portal che gira all'interno della tua app. A tale scopo, aggiungere un nuovo componente WinRT all'applicazione con una classe che implementa IBackgroundTask.
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;
//...
}
Assicurarsi che il nome corrisponda allo spazio dei nomi e al nome della classe impostati da AppService EntryPoint ("MySampleProvider.SampleProvider"). Quando si effettua la prima richiesta al provider del portale di dispositivi, Device Portal archivierà la richiesta, avvierà l'attività in background dell'app, chiamerà il relativo metodo Run e passerà un IBackgroundTaskInstance. Quindi l'app usa quest'ultimo per configurare un'istanza di DevicePortalConnection.
// 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;
}
Esistono due eventi che devono essere gestiti dall'app per completare il ciclo di gestione delle richieste: Chiuso, per ogni volta che il servizio Device Portal si arresta e RequestReceived, che espone le richieste HTTP in ingresso e fornisce la funzionalità principale del provider del portale di dispositivi.
Gestire l'evento RequestReceived
L'evento RequestReceived verrà generato un'unica volta per ogni richiesta HTTP effettuata sul percorso gestore specificato del plug-in. Il ciclo di gestione delle richieste per i provider di Device Portal è simile a quello in NodeJS Express: gli oggetti richiesta e risposta vengono forniti insieme all'evento e il gestore risponde compilando l'oggetto risposta. Nei provider di Portale di dispositivi, l'evento RequestReceived e i relativi gestori usano gli oggetti Windows.Web.Http.HttpRequestMessage e HttpResponseMessage.
// 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 questo gestore di richieste di esempio, si estraggono prima gli oggetti di richiesta e risposta dal parametro argomento, quindi si crea una stringa con l'URL della richiesta e con una formattazione HTML aggiuntiva. Viene aggiunto all'oggetto Response come istanza di HttpStringContent. Sono consentite anche altre classi IHttpContent , ad esempio quelle per "String" e "Buffer".
La risposta viene quindi impostata come risposta HTTP e viene fornito un codice di stato 200 (OK). Dovrebbe essere eseguito il rendering come previsto nel browser che ha effettuato la chiamata originale. Si noti che quando viene restituito il gestore eventi RequestReceived , il messaggio di risposta viene restituito automaticamente all'agente utente: non è necessario alcun metodo "send" aggiuntivo.
Fornitura di contenuto statico
Il contenuto statico può essere fornito direttamente da una cartella all'interno del pacchetto, semplificando l'aggiunta di un'interfaccia utente al provider. Il modo più semplice per gestire il contenuto statico consiste nel creare una cartella di contenuto nel progetto in grado di eseguire il mapping a un URL.
Aggiungere quindi un gestore di route nel gestore eventi RequestReceived che rileva le route di contenuto statico e esegue il mapping appropriato di una richiesta.
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");
}
}
Assicurarsi che tutti i file all'interno della cartella del contenuto siano contrassegnati come "Contenuto" e impostare su "Copia se più recente" o "Copia sempre" nel menu Proprietà di Visual Studio. In questo modo si garantisce che i file si trovino all'interno del pacchetto AppX durante la distribuzione.
Uso di risorse e API di Device Portal esistenti
Il contenuto statico gestito da un provider di Portale di dispositivi viene fornito sulla stessa porta del servizio Core Device Portal. Ciò significa che è possibile fare riferimento ai file JS e CSS esistenti inclusi in Device Portal con semplici tag <link>
e <script>
nel codice HTML. In generale, è consigliabile usare rest.js, che esegue il wrapping di tutte le API REST principali del Portale dei dispositivi in un pratico oggetto webbRest e il file common.css, che consente di applicare uno stile al contenuto in modo che si adatti al resto dell'interfaccia utente del Portale dei dispositivi. È possibile visualizzare un esempio nella pagina index.html inclusa nell'esempio. Usa rest.js per recuperare il nome del dispositivo e i processi in esecuzione da Device Portal.
output del plug-in del portale dei dispositivi
Importante, l'uso dei metodi HttpPost/DeleteExpect200 su webbRest eseguirà automaticamente la gestione CSRF, che consente alla pagina Web di chiamare API REST che cambiano stato.
Annotazioni
Il contenuto statico incluso in Device Portal non offre una garanzia contro modifiche che possano causare malfunzionamenti. Anche se le API non devono cambiare spesso, possono, soprattutto nei file common.js e controls.js, che il tuo provider non dovrebbe usare.
Debug della connessione di Device Portal
Per eseguire il debug dell'attività in background, è necessario modificare il modo in cui Visual Studio esegue il codice. Seguire questa procedura per eseguire il debug di una connessione al servizio app per controllare come il provider gestisce le richieste HTTP:
- Scegliere Proprietà DevicePortalProvider dal menu Debug.
- Nella sezione Azione di avvio della scheda Debug, selezionare "Non avviare, ma eseguire il debug del codice all'avvio".
- Impostare un punto di interruzione nella funzione del gestore RequestReceived.
Annotazioni
Assicurarsi che l'architettura del build corrisponda esattamente all'architettura dell'obiettivo. Se si usa un PC a 64 bit, è necessario eseguire la distribuzione con una build AMD64. 4. Premere F5 per distribuire l'app 5. Disattivare Device Portal, quindi riattivarlo in modo che trovi l'app (necessaria solo quando modifichi il manifesto dell'app, il resto del tempo puoi semplicemente ri-distribuire e ignorare questo passaggio). 6. Nel browser, accedi allo spazio dei nomi del provider e il punto di interruzione verrà raggiunto.