Creare app ospitate

A partire da Windows 10 versione 2004, è possibile creare app in hosting. Le app in hosting ospitate condividono lo stesso eseguibile e la stessa definizione di un'app host padre , ma hanno l'aspetto e i comportamenti di un'app separata nel sistema.

Le app ospitate sono utili per gli scenari in cui si vuole che un componente, ad esempio un file eseguibile o un file di script, si comporti come un'app di Windows 10 autonoma, ma il componente richiede un processo host per poter essere eseguito. Ad esempio, uno script di PowerShell o Python può essere distribuito come app in hosting che richiede l'installazione di un host per l'esecuzione. Un'app ospitata può avere un proprio riquadro iniziale, un'identità e un'integrazione completa con le funzionalità di Windows 10, ad esempio le attività in background, le notifiche, i riquadri e le destinazioni di condivisione.

La funzionalità app in hosting è supportata da diversi elementi e attributi nel manifesto del pacchetto che consentono a un'app in hosting di usare un eseguibile e una definizione in un pacchetto dell'app host. Quando un utente esegue l'app in hosting, il sistema operativo avvia automaticamente l'eseguibile host con l'identità dell'app in hosting. L'host può quindi caricare gli asset visivi, il contenuto o chiamare le API come app in hosting. L'app in hosting ottiene l'intersezione delle funzionalità dichiarate tra l'host e l'app in hosting. Ciò significa che un'app in hosting non può richiedere più funzionalità rispetto a quelle offerte dall'host.

Definire un host

L'host è il processo eseguibile o di runtime principale per l'app in hosting. Attualmente, gli unici host supportati sono le app desktop (.NET o C++ desktop) con identità del pacchetto. Esistono diversi modi per un'app desktop per avere l'identità del pacchetto:

L'host viene dichiarato nel manifesto del pacchetto dall'estensione uap10:HostRuntime . Questa estensione ha un attributo Id a cui deve essere assegnato un valore a cui fa riferimento anche il manifesto del pacchetto per l'app in hosting. Quando l'app in hosting viene attivata, l'host viene avviato con l'identità dell'app in hosting e può caricare contenuto o file binari dal pacchetto dell'app in hosting.

Nell'esempio seguente viene illustrato come definire un host in un manifesto del pacchetto. L'estensione uap10:HostRuntime è a livello di pacchetto e viene quindi dichiarata come figlio dell'elemento Package.

<Package xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10">

  <Extensions>
    <uap10:Extension Category="windows.hostRuntime"  
        Executable="PyScriptEngine\PyScriptEngine.exe"  
        uap10:RuntimeBehavior="packagedClassicApp"  
        uap10:TrustLevel="mediumIL">
      <uap10:HostRuntime Id="PythonHost" />
    </uap10:Extension>
  </Extensions>

</Package>

Prendere nota di questi importanti dettagli sugli elementi seguenti.

Elemento Dettagli
uap10:Extension La categoria windows.hostRuntime dichiara un'estensione a livello di pacchetto che definisce le informazioni di runtime da usare quando si attiva un'app in hosting. Un'app in hosting verrà eseguita con le definizioni dichiarate nell'estensione. Quando si usa l'app host dichiarata nell'esempio precedente, un'app in hosting verrà eseguita come eseguibile PyScriptEngine.exe a livello di attendibilità mediumIL.

Gli attributi Eseguibili, uap10:RuntimeBehavior e uap10:TrustLevel specificano il nome del file binario del processo host nel pacchetto e la modalità di esecuzione delle app in hosting. Ad esempio, un'app in hosting che usa gli attributi dell'esempio precedente verrà eseguita come eseguibile PyScriptEngine.exe a livello di attendibilità mediumIL.
uap10:HostRuntime L'attributo Id dichiara l'identificatore univoco di questa specifica app host nel pacchetto. Un pacchetto può avere più app host e ognuna deve avere un elemento uap10:HostRuntime con un ID univoco.

Dichiarare un'app in hosting

Un'app in hosting dichiara una dipendenza del pacchetto da un host. L'app in hosting sfrutta l'ID dell'host, ovvero l'attributo Id dell'estensione uap10:HostRuntime nel pacchetto host, per l'attivazione anziché specificare un eseguibile del punto di ingresso nel proprio pacchetto. L'app in hosting contiene in genere contenuto, asset visivi, script o file binari a cui è possibile accedere dall'host. Il valore TargetDeviceFamily nel pacchetto dell'app in hosting deve essere lo stesso valore dell'host.

I pacchetti dell'app in hosting possono essere firmati o non firmati:

  • I pacchetti firmati possono contenere file eseguibili. Ciò è utile negli scenari con un meccanismo di estensione binaria, che consente all'host di caricare una DLL o un componente registrato nel pacchetto dell'app in hosting.
  • Nella maggior parte degli scenari, il pacchetto non firmato conterrà contenuto eseguibile. Tuttavia, un pacchetto non firmato che contiene solo file non eseguibili è utile negli scenari in cui l'host deve caricare solo immagini, asset e file di contenuto o script. I pacchetti non firmati devono includere un valore speciale OID nell'elemento Identity o non saranno autorizzati a registrarsi. In questo modo, i pacchetti non firmati non possono essere in conflitto con o spoofing dell'identità di un pacchetto firmato.

Per definire un'app in hosting, dichiarare gli elementi seguenti nel manifesto del pacchetto:

L'esempio seguente illustra le sezioni pertinenti di un manifesto del pacchetto per un'app in hosting non firmata.

<Package xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10">

  <Identity Name="NumberGuesserManifest"
    Publisher="CN=AppModelSamples, OID.2.25.311729368913984317654407730594956997722=1"
    Version="1.0.0.0" />

  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
    <uap10:HostRuntimeDependency Name="PyScriptEnginePackage" Publisher="CN=AppModelSamples" MinVersion="1.0.0.0"/>
  </Dependencies>

  <Applications>
    <Application Id="NumberGuesserApp"  
      uap10:HostId="PythonHost"  
      uap10:Parameters="-Script &quot;NumberGuesser.py&quot;">
    </Application>
  </Applications>

</Package>

Prendere nota di questi importanti dettagli sugli elementi seguenti.

Elemento Dettagli
Identità Poiché il pacchetto dell'app in hosting in questo esempio non è firmato, l'attributo Publisher deve includere la stringa OID.2.25.311729368913984317654407730594956997722=1. In questo modo, il pacchetto non firmato non può eseguire lo spoofing dell'identità di un pacchetto firmato.
TargetDeviceFamily L'attributo MinVersion deve specificare 10.0.19041.0 o una versione successiva del sistema operativo.
uap10:HostRuntimeDependency Questo elemento dichiara una dipendenza dal pacchetto dell'app host. Ciò consiste in Nome e Publisher del pacchetto host e la MinVersion da cui dipende. Questi valori sono disponibili sotto l'elemento Identity nel pacchetto host.
Applicazione L'attributo uap10:HostId esprime la dipendenza dall'host. Il pacchetto dell'app in hosting deve dichiarare questo attributo invece degli attributi Eseguibile e EntryPoint consueti per una Applicazione o un elemento di Estensione. Di conseguenza, l'app in hosting eredita gli attributi Eseguibile, EntryPoint e runtime dall'host con il valore HostId corrispondente.

L'attributo uap10:Parameters specifica i parametri passati alla funzione del punto di ingresso dell'eseguibile dell'host. Poiché l'host deve sapere cosa fare con questi parametri, esiste un contratto implicito tra l'host e l'app in hosting.

Registrare un pacchetto app in hosting non firmato in fase di esecuzione

Uno dei vantaggi dell'estensione uap10:HostRuntime è che consente a un host di generare dinamicamente un pacchetto dell'app in hosting in fase di esecuzione e registrarlo usando l'API PackageManager, senza doverlo firmare. Ciò consente a un host di generare dinamicamente il contenuto e il manifesto per il pacchetto dell'app in hosting e quindi registrarlo.

Usare i metodi seguenti della classe PackageManager per registrare un pacchetto app in hosting non firmato. Questi metodi sono disponibili a partire da Windows 10, versione 2004.

  • AddPackageByUriAsync: registra un pacchetto MSIX non firmato usando la proprietà AllowUnsigned del parametro options.
  • RegisterPackageByUriAsync: esegue una registrazione di un file manifesto del pacchetto libero. Se il pacchetto è firmato, la cartella contenente il manifesto deve includere un file con estensione p7x e un catalogo. Se non firmata, è necessario impostare la proprietà AllowUnsigned del parametro options.

Requisiti per le app in hosting non firmate

  • Gli elementi Application o Extension nel manifesto del pacchetto non possono contenere dati di attivazione, ad esempio gli attributi Executable, EntryPoint, o TrustLevel. Questi elementi possono invece contenere un solo attributo uap10:HostId che esprime la dipendenza dall'host e da un attributo uap10:Parameters.
  • Il pacchetto deve essere un pacchetto principale. Non può essere un bundle, un pacchetto framework, una risorsa o un pacchetto facoltativo.

Requisiti per un host che installa e registra un pacchetto app in hosting non firmato

  • L'host deve avere l'identità del pacchetto.
  • L'host deve avere la funzionalità con limitazioni packageManagement.
    <rescap:Capability Name="packageManagement" />
    

Esempio

Per un'app di esempio completamente funzionale che dichiara se stessa come host e quindi registra dinamicamente un pacchetto di app in hosting in fase di esecuzione, vedere l'esempio di app in hosting.

Host

L'host è denominato PyScriptEngine. Si tratta di un wrapper scritto in C# che esegue script Python. Quando viene eseguito con il parametro -Register, il motore dello script installa un'app in hosting contenente uno script Python. Quando un utente tenta di avviare l'app in hosting appena installata, l'host viene avviato ed esegue lo script Python NumberGuesser.

Il manifesto del pacchetto per l'app host (il file Package.appxmanifest nella cartella PyScriptEnginePackage) contiene un'estensione uap10:HostRuntime che dichiara l'app come host con ID PythonHost e l'eseguibile PyScriptEngine.exe.

Nota

In questo esempio il manifesto del pacchetto è denominato Package.appxmanifest e fa parte di un progetto di creazione di pacchetti di applicazioni Windows. Quando questo progetto viene compilato, genera un manifesto denominato AppxManifest.xml e compila il pacchetto MSIX per l'app host.

App in hosting

L'app in hosting è costituita da uno script Python e da elementi del pacchetto, ad esempio il manifesto del pacchetto. Non contiene file PE.

Il manifesto del pacchetto per l'app in hosting (il file NumberGuesser/AppxManifest.xml) contiene gli elementi seguenti:

  • L'attributo Publisher dell'elemento Identity contiene l'identificatore OID.2.25.311729368913984317654407730594956997722=1, necessario per un pacchetto non firmato.
  • L'attributo uap10:HostId dell'elemento Application identifica PythonHost come host.

Eseguire l'esempio

L'esempio richiede la versione 10.0.19041.0 o successiva di Windows 10 e Windows SDK.

  1. Scaricare l'esempio in una cartella nel computer di sviluppo.

  2. Aprire il file della soluzione PyScriptEngine.sln in Visual Studio 2019 e impostare il progetto PyScriptEnginePackage come progetto di avvio.

  3. Compilare il progetto PyScriptEnginePackage.

  4. In Esplora soluzioni fare clic con il tasto destro del mouse sul progetto PyScriptEnginePackage e selezionare Distribuisci.

  5. Aprire una finestra del prompt dei comandi nella directory in cui sono stati copiati i file di esempio ed eseguire il comando seguente per registrare l'app NumberGuesser di esempio (l'app in hosting). Passare D:\repos\HostedApps al percorso in cui sono stati copiati i file di esempio.

    D:\repos\HostedApps>pyscriptengine -Register D:\repos\HostedApps\NumberGuesser\AppxManifest.xml
    

    Nota

    È possibile eseguire pyscriptengine nella riga di comando perché l'host nell'esempio dichiara un AppExecutionAlias.

  6. Aprire il menu Start e fare clic su NumberGuesser per eseguire l'app in hosting.