Creare e ospitare un'estensione di app

Questo articolo illustra come creare un'estensione dell'app di Windows 10 e ospitarla in un'app. Le estensioni dell'app sono supportate nelle app UWP e nelle app desktop in pacchetto.

Per illustrare come creare un'estensione dell'app, questo articolo usa il codice XML del manifesto del pacchetto e i frammenti di codice dell'esempio di codice dell'estensione matematica. Questo esempio è un'app UWP, ma le funzionalità illustrate nell'esempio sono applicabili anche alle app desktop in pacchetto. Per iniziare a usare questo esempio, seguire queste istruzioni:

  • Scaricare e decomprimere l'esempio di codice dell'estensione matematica.
  • In Visual Studio 2019 aprire MathExtensionSample.sln. Impostare il tipo di compilazione su x86 (Build>Configuration Manager, quindi modificare Platform in x86 per entrambi i progetti).
  • Distribuire la soluzione: Compilare la>soluzione di distribuzione.

Introduzione alle estensioni dell'app

In Windows 10, le estensioni di app forniscono funzionalità simili a quelle fornite da plug-in e componenti aggiuntivi su altre piattaforme. Le estensioni di app sono state introdotte nell'edizione dell'anniversario di Windows 10 (versione 1607, build 10.0.14393).

Le estensioni dell'app sono app UWP o app desktop in pacchetto con una dichiarazione di estensione che consente loro di condividere eventi di contenuto e distribuzione con un'app host. Un'app di estensione può fornire più estensioni.

Poiché le estensioni delle app sono solo app UWP o app desktop in pacchetto, possono anche essere app completamente funzionali, estensioni host e fornire estensioni ad altre app, senza creare pacchetti di app separati.

Quando si crea un host di estensione dell'app, si crea un'opportunità per sviluppare un ecosistema intorno all'app in cui altri sviluppatori possono migliorare l'app in modi per cui potresti non avere previsto o avere le risorse. Prendere in considerazione le estensioni di Microsoft Office, le estensioni di Visual Studio, le estensioni del browser e così via. Questi creano esperienze più avanzate per le app che vanno oltre le funzionalità fornite. Le estensioni possono aggiungere valore e longevità all'app.

A livello generale, per configurare una relazione di estensione dell'app, è necessario:

  1. Dichiarare un'app come host di estensione.
  2. Dichiarare un'app come estensione.
  3. Decidere se implementare l'estensione come servizio app, attività in background o altro.
  4. Definire il modo in cui gli host e le relative estensioni comunicheranno.
  5. Usare l'API Windows.ApplicationModel.AppExtensions nell'app host per accedere alle estensioni.

Vediamo come questa operazione viene eseguita esaminando l'esempio di codice dell'estensione matematica che implementa una calcolatrice ipotetica a cui è possibile aggiungere nuove funzioni usando le estensioni. In Microsoft Visual Studio 2019 caricare MathExtensionSample.sln dall'esempio di codice.

Math Extension code sample

Dichiarare un'app come host di estensione

Un'app si identifica come un'app di estensione del pacchetto dichiarando <AppExtensionHost> l'elemento nel file Package.appxmanifest. Vedere il file Package.appxmanifest nel progetto MathExtensionHost per vedere come viene eseguita questa operazione.

Aprire il file Package.appxmanifest nel progetto MathExtensionHos

<Package
  ...
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  IgnorableNamespaces="uap uap3 mp">
  ...
    <Applications>
      <Application Id="App" ... >
        ...
        <Extensions>
            <uap3:Extension Category="windows.appExtensionHost">
                <uap3:AppExtensionHost>
                  <uap3:Name>com.microsoft.mathext</uap3:Name>
                </uap3:AppExtensionHost>
          </uap3:Extension>
        </Extensions>
      </Application>
    </Applications>
    ...
</Package>

Si noti xmlns:uap3="http://..." e la presenza di uap3 in IgnorableNamespaces. Questi sono necessari perché si usa lo spazio dei nomi uap3.

<uap3:Extension Category="windows.appExtensionHost"> identifica questa app come host di estensione.

L'elemento Nome in <uap3:AppExtensionHost> è il nome del contratto di estensione. Quando un'estensione specifica lo stesso nome del contratto di estensione, l'host sarà in grado di trovarlo. Per convenzione, è consigliabile creare il nome del contratto di estensione usando l'app o il nome dell'editore per evitare potenziali conflitti con altri nomi di contratto di estensione.

È possibile definire più host e più estensioni nella stessa app. In questo esempio viene dichiarato un host. L'estensione è definita in un'altra app.

Dichiarare un'app come estensione

Un'app si identifica come un'app di estensione del pacchetto dichiarando <uap3:AppExtension> l'elemento nel suo file Package.appxmanifest. Aprire il file Package.appxmanifest nel progetto MathExtension per vedere come viene eseguita questa operazione.

Aprire il file Package.appxmanifest nel progetto MathExtension:

<Package
  ...
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  IgnorableNamespaces="uap uap3 mp">
  ...
    <Applications>
      <Application Id="App" ... >
        ...
        <Extensions>
          ...
          <uap3:Extension Category="windows.appExtension">
            <uap3:AppExtension Name="com.microsoft.mathext"
                               Id="power"
                               DisplayName="x^y"
                               Description="Exponent"
                               PublicFolder="Public">
              <uap3:Properties>
                <Service>com.microsoft.powservice</Service>
              </uap3:Properties>
              </uap3:AppExtension>
          </uap3:Extension>
        </Extensions>
      </Application>
    </Applications>
    ...
</Package>

Anche in questo caso, notare la riga xmlns:uap3="http://..." e la presenza di uap3 in IgnorableNamespaces. Questi sono necessari perché si usa lo spazio dei nomi uap3.

<uap3:Extension Category="windows.appExtension"> identifica questa app come estensione.

Il significato degli attributi <uap3:AppExtension> è il seguente:

Attributo Descrizione Richiesto
Nome Si tratta del nome del contratto di estensione. Quando corrisponde al nome dichiarato in un host, tale host sarà in grado di trovare questa estensione. ✔️
ID Identifica in modo univoco questa estensione. Poiché possono essere presenti più estensioni che usano lo stesso nome del contratto di estensione (si supponga che un'app paint supporti diverse estensioni), è possibile usare l'ID per distinguerli. Gli host dell'estensione dell'app possono usare l'ID per dedurre qualcosa sul tipo di estensione. Ad esempio, è possibile avere un'estensione progettata per desktop e un'altra per dispositivi mobili, con l'ID che rappresenta il differenziatore. È anche possibile usare l'elemento Proprietà, illustrato di seguito, per tale elemento. ✔️
DisplayName Può essere usato dall'app host per identificare l'estensione per l'utente. È possibile eseguire query e può usare il nuovo sistema di gestione delle risorse (ms-resource:TokenName) per la localizzazione. Il contenuto localizzato viene caricato dal pacchetto di estensione dell'app, non dall'app host.
Descrizione Può essere usato dall'app host per descrivere l'estensione per l'utente. È possibile eseguire query e può usare il nuovo sistema di gestione delle risorse (ms-resource:TokenName) per la localizzazione. Il contenuto localizzato viene caricato dal pacchetto di estensione dell'app, non dall'app host.
Cartella pubblica Nome di una cartella, relativa alla radice del pacchetto, in cui è possibile condividere il contenuto con l'host dell'estensione. Per convenzione, il nome è "Pubblico", ma è possibile usare qualsiasi nome corrispondente a una cartella nell'estensione. ✔️

<uap3:Properties> è un elemento facoltativo che contiene metadati personalizzati che gli host possono leggere in fase di esecuzione. Nell'esempio di codice, l'estensione viene implementata come servizio app in modo che l'host richieda un modo per ottenere il nome del servizio app in modo che possa chiamarlo. Il nome del servizio app è definito nell'elemento <Service> definito (avremmo potuto chiamarlo come volevamo). L'host nell'esempio di codice cerca questa proprietà in fase di esecuzione per apprendere il nome del servizio app.

Decidere come implementare l'estensione.

La sessione Build 2016 sulle estensioni dell'app illustra come usare la cartella pubblica condivisa tra l'host e le estensioni. In questo esempio, l'estensione viene implementata da un file JavaScript archiviato nella cartella pubblica, che l'host richiama. Questo approccio ha il vantaggio di essere leggero, non richiede la compilazione e può supportare la creazione della pagina di destinazione predefinita che fornisce istruzioni per l'estensione e un collegamento alla pagina di Microsoft Store dell'app host. Per informazioni dettagliate, vedere l'esempio di codice di estensione dell'app Build 2016. In particolare, vedere il progetto InvertImageExtension e InvokeLoad() in ExtensionManager.cs nel progetto ExtensibilitySample.

In questo esempio si userà un servizio app per implementare l'estensione. I servizi app presentano i vantaggi seguenti:

  • Se l'estensione si arresta in modo anomalo, l'app host non viene arrestata perché l'app host viene eseguita nel proprio processo.
  • È possibile usare il linguaggio preferito per implementare il servizio. Non deve corrispondere alla lingua usata per implementare l'app host.
  • Il servizio app ha accesso al proprio contenitore di app, che può avere funzionalità diverse rispetto all'host.
  • Esiste un isolamento tra i dati nel servizio e nell'app host.

Codice del servizio app host

Ecco il codice host che richiama il servizio app dell'estensione:

ExtensionManager.cs nel progetto MathExtensionHost

public async Task<double> Invoke(ValueSet message)
{
    if (Loaded)
    {
        try
        {
            // make the app service call
            using (var connection = new AppServiceConnection())
            {
                // service name is defined in appxmanifest properties
                connection.AppServiceName = _serviceName;
                // package Family Name is provided by the extension
                connection.PackageFamilyName = AppExtension.Package.Id.FamilyName;

                // open the app service connection
                AppServiceConnectionStatus status = await connection.OpenAsync();
                if (status != AppServiceConnectionStatus.Success)
                {
                    Debug.WriteLine("Failed App Service Connection");
                }
                else
                {
                    // Call the app service
                    AppServiceResponse response = await connection.SendMessageAsync(message);
                    if (response.Status == AppServiceResponseStatus.Success)
                    {
                        ValueSet answer = response.Message as ValueSet;
                        if (answer.ContainsKey("Result")) // When our app service returns "Result", it means it succeeded
                        {
                            return (double)answer["Result"];
                        }
                    }
                }
            }
        }
        catch (Exception)
        {
             Debug.WriteLine("Calling the App Service failed");
        }
    }
    return double.NaN; // indicates an error from the app service
}

Questo è il codice tipico per richiamare un servizio app. Per informazioni dettagliate su come implementare e chiamare un servizio app, vedere Come creare e usare un servizio app.

Un aspetto da notare è il modo in cui viene determinato il nome del servizio app da chiamare. Poiché l'host non dispone di informazioni sull'implementazione dell'estensione, l'estensione deve fornire il nome del servizio app. Nell'esempio di codice l'estensione dichiara il nome del servizio app nel relativo file nell'elemento <uap3:Properties>:

Aprire il file Package.appxmanifest nel progetto MathExtension

    ...
    <uap3:Extension Category="windows.appExtension">
      <uap3:AppExtension ...>
        <uap3:Properties>
          <Service>com.microsoft.powservice</Service>
        </uap3:Properties>
        </uap3:AppExtension>
    </uap3:Extension>

È possibile definire il proprio codice XML nell'elemento <uap3:Properties>. In questo caso, definiamo il nome del servizio app in modo che l'host possa richiamarlo quando richiama l'estensione.

Quando l'host carica un'estensione, il codice seguente estrae il nome del servizio dalle proprietà definite nell'estensione Package.appxmanifest:

Update() in ExtensionManager.cs, nel progetto MathExtensionHost

...
var properties = await ext.GetExtensionPropertiesAsync() as PropertySet;

...
#region Update Properties
// update app service information
_serviceName = null;
if (_properties != null)
{
   if (_properties.ContainsKey("Service"))
   {
       PropertySet serviceProperty = _properties["Service"] as PropertySet;
       this._serviceName = serviceProperty["#text"].ToString();
   }
}
#endregion

Con il nome del servizio app archiviato in _serviceName, l'host è in grado di usarlo per richiamare il servizio app.

Per chiamare un servizio app è necessario anche il nome della famiglia del pacchetto che contiene il servizio app. Fortunatamente, l'API dell'estensione dell'app fornisce queste informazioni ottenute nella riga: connection.PackageFamilyName = AppExtension.Package.Id.FamilyName;

Definire il modo in cui l'host e l'estensione comunicheranno

I servizi app usano un ValueSet per scambiare informazioni. L'autore dell'host deve avere un protocollo per comunicare con le estensioni flessibili. Nell'esempio di codice ciò significa tenere conto delle estensioni che possono richiedere 1, 2 o più argomenti in futuro.

Per questo esempio, il protocollo per gli argomenti è un ValueSet contenente le coppie chiave-valore denominate 'Arg' + il numero di argomento, ad esempio Arg1 e Arg2. L'host passa tutti gli argomenti in ValueSet e l'estensione usa quelle necessarie. Se l'estensione è in grado di calcolare un risultato, l'host prevede che l'oggetto ValueSet restituito dall'estensione disponga di una chiave denominata Result contenente il valore del calcolo. Se tale chiave non è presente, l'host presuppone che l'estensione non sia riuscita a completare il calcolo.

Estensione del codice di servizio app

Nell'esempio di codice il servizio app dell'estensione non viene implementato come attività in background. Usa invece il modello di servizio app single proc in cui viene eseguito il servizio app nello stesso processo dell'app di estensione che lo ospita. Questo è ancora un processo diverso dall'app host, offrendo i vantaggi della separazione dei processi, ottenendo alcuni vantaggi in termini di prestazioni evitando la comunicazione tra processi tra il processo di estensione e il processo in background che implementa il servizio app. Vedere Convertire un servizio app in modo che venga eseguito nello stesso processo dell'app host per vedere la differenza tra un servizio app eseguito come attività in background rispetto allo stesso processo.

Il sistema esegue quando OnBackgroundActivate() viene attivato il servizio app. Tale codice configura i gestori eventi per gestire la chiamata effettiva del servizio app quando si tratta di (OnAppServiceRequestReceived()) e di gestire eventi di manutenzione come il recupero di un oggetto differente che gestisce un evento di annullamento o chiuso.

App.xaml.cs nel progetto MathExtension.

protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
    base.OnBackgroundActivated(args);

    if ( _appServiceInitialized == false ) // Only need to setup the handlers once
    {
        _appServiceInitialized = true;

        IBackgroundTaskInstance taskInstance = args.TaskInstance;
        taskInstance.Canceled += OnAppServicesCanceled;

        AppServiceTriggerDetails appService = taskInstance.TriggerDetails as AppServiceTriggerDetails;
        _appServiceDeferral = taskInstance.GetDeferral();
        _appServiceConnection = appService.AppServiceConnection;
        _appServiceConnection.RequestReceived += OnAppServiceRequestReceived;
        _appServiceConnection.ServiceClosed += AppServiceConnection_ServiceClosed;
    }
}

Il codice che esegue il lavoro dell'estensione è in OnAppServiceRequestReceived(). Questa funzione viene chiamata quando viene richiamato il servizio app per eseguire un calcolo. Estrae i valori necessari da ValueSet. Se può eseguire il calcolo, inserisce il risultato, sotto una chiave denominata Result, nel ValueSet restituito all'host. Tenere presente che in base al protocollo definito per il modo in cui l'host e le relative estensioni comunicheranno, la presenza di una chiave Result indicherà l'esito positivo; in caso contrario, l'esito negativo.

App.xaml.cs nel progetto MathExtension.

private async void OnAppServiceRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
{
    // Get a deferral because we use an awaitable API below (SendResponseAsync()) to respond to the message
    // and we don't want this call to get cancelled while we are waiting.
    AppServiceDeferral messageDeferral = args.GetDeferral();
    ValueSet message = args.Request.Message;
    ValueSet returnMessage = new ValueSet();

    double? arg1 = Convert.ToDouble(message["arg1"]);
    double? arg2 = Convert.ToDouble(message["arg2"]);
    if (arg1.HasValue && arg2.HasValue)
    {
        returnMessage.Add("Result", Math.Pow(arg1.Value, arg2.Value)); // For this sample, the presence of a "Result" key will mean the call succeeded
    }

    await args.Request.SendResponseAsync(returnMessage);
    messageDeferral.Complete();
}

Gestire le estensioni

Ora che abbiamo visto come implementare la relazione tra un host e le relative estensioni, vediamo come un host trova le estensioni installate nel sistema e reagisce all'aggiunta e alla rimozione di pacchetti contenenti estensioni.

Microsoft Store offre estensioni come pacchetti. AppExtensionCatalog trova i pacchetti installati che contengono estensioni corrispondenti al nome del contratto di estensione dell'host e fornisce eventi che vengono generati quando viene installato o rimosso un pacchetto di estensione dell'app rilevante per l'host.

Nell'esempio di codice, la ExtensionManager classe (definita in ExtensionManager.cs nel progetto MathExtensionHost) esegue il wrapping della logica per il caricamento delle estensioni e la risposta alle installazioni e alla disinstallazione del pacchetto di estensione.

Il ExtensionManager costruttore usa AppExtensionCatalog per trovare le estensioni dell'app nel sistema con lo stesso nome del contratto di estensione dell'host:

ExtensionManager.cs nel progetto MathExtensionHost.

public ExtensionManager(string extensionContractName)
{
   // catalog & contract
   ExtensionContractName = extensionContractName;
   _catalog = AppExtensionCatalog.Open(ExtensionContractName);
   ...
}

Quando viene installato un pacchetto di estensione, ExtensionManager raccoglie informazioni sulle estensioni nel pacchetto con lo stesso nome del contratto di estensione dell'host. Un'installazione può rappresentare un aggiornamento nel qual caso le informazioni sull'estensione interessata vengono aggiornate. Quando un pacchetto di estensione viene disinstallato, ExtensionManager rimuove le informazioni sulle estensioni interessate in modo che l'utente conosca quali estensioni non sono più disponibili.

La Extension classe (definita in ExtensionManager.cs nel progetto MathExtensionHost) è stata creata per l'esempio di codice per accedere all'ID, alla descrizione, al logo e alle informazioni specifiche dell'app di un'estensione, ad esempio se l'utente ha abilitato l'estensione.

Per dire che l'estensione viene caricata (vedere Load() in ExtensionManager.cs) significa che lo stato del pacchetto è corretto e che abbiamo ottenuto il relativo ID, logo, descrizione e cartella pubblica (che non usiamo in questo esempio, solo per mostrare come ottenerlo). Il pacchetto di estensione stesso non viene caricato.

Il concetto di scaricamento viene usato per tenere traccia delle estensioni che non devono più essere presentate all'utente.

ExtensionManager fornisce istanze di raccolta Extension in modo che le estensioni, i relativi nomi, descrizioni e logo possano essere associati a dati all'interfaccia utente. La pagina ExtensionsTab viene associata a questa raccolta e fornisce l'interfaccia utente per abilitare/disabilitare le estensioni e rimuoverle.

Extensions tab example UI

Quando un'estensione viene rimossa, il sistema chiede all'utente di verificare che voglia disinstallare il pacchetto che contiene l'estensione (e possibilmente contiene altre estensioni). Se l'utente accetta, il pacchetto viene disinstallato e ExtensionManager rimuove le estensioni nel pacchetto disinstallato dall'elenco di estensioni disponibili per l'app host.

Uninstall UI

Debug di estensioni e host dell'app

Spesso, l'host di estensione e l'estensione non fanno parte della stessa soluzione. In tal caso, per eseguire il debug dell'host e dell'estensione:

  1. Caricare il progetto host in un'istanza di Visual Studio.
  2. Caricare l'estensione in un'altra istanza di Visual Studio.
  3. Avviare l'app host nel debugger.
  4. Avviare l'app di estensione nel debugger. Se si vuole distribuire l'estensione, anziché eseguirne il debug, per testare l'evento di installazione del pacchetto dell'host, eseguire Compilare> invece di Distribuisci soluzione).

A questo punto sarà possibile raggiungere i punti di interruzione nell'host e nell'estensione. Se si avvia il debug dell'app di estensione stessa, verrà visualizzata una finestra vuota per l'app. Se non si vuole visualizzare la finestra vuota, è possibile modificare le impostazioni di debug per il progetto di estensione per non avviare l'app, ma eseguirne il debug all'avvio (fare clic con il pulsante destro del mouse sul progetto di estensione, Proprietà>Debug> selezionare Non avviare, ma eseguire il debug del codice all'avvio) È comunque necessario avviare il debug (F5) il progetto di estensione, ma attenderà fino a quando l'host attiva l'estensione e i punti di interruzione nell'estensione verranno raggiunti.

Eseguire il debug del codice di esempio

Nell'esempio di codice l'host e l'estensione si trovano nella stessa soluzione. Per eseguire il debug procedere nel modo seguente:

  1. Assicurarsi che MathExtensionHost sia il progetto di avvio (fare clic con il tasto destro del mouse sul progetto MathExtensionHost, selezionare Imposta come progetto di avvio).
  2. Inserire un punto di interruzione Invoke in ExtensionManager.cs, nel progetto MathExtensionHost.
  3. F5 per eseguire il progetto MathExtensionHost.
  4. Posizionare un punto di interruzione OnAppServiceRequestReceived in App.xaml.cs nel progetto MathExtension.
  5. Avviare il debug del progetto MathExtension (fare clic con il pulsante destro del mouse sul progetto MathExtension, Debug > Avvia nuova istanza) che lo distribuirà e attiverà l'evento di installazione del pacchetto nell'host.
  6. Nell'app MathExtensionHost passare alla pagina Calcolo e fare clic su x^y per attivare l'estensione. Il Invoke() punto di interruzione viene raggiunto per primo ed è possibile visualizzare la chiamata al servizio app delle estensioni in corso. Viene quindi raggiunto il metodo OnAppServiceRequestReceived() nell'estensione e il servizio app calcola il risultato e lo restituisce.

Risoluzione dei problemi delle estensioni implementate come servizio app

Se l'host dell'estensione presenta problemi di connessione al servizio app per l'estensione, assicurarsi che l'attributo <uap:AppService Name="..."> corrisponda a quello inserito nell'elemento<Service>. Se non corrispondono, il nome del servizio fornito dall'estensione non corrisponderà al nome del servizio app implementato e l'host non sarà in grado di attivare l'estensione.

Aprire il file Package.appxmanifest nel progetto MathExtension:

<Extensions>
   <uap:Extension Category="windows.appService">
     <uap:AppService Name="com.microsoft.sqrtservice" />      <!-- This must match the contents of <Service>...</Service> -->
   </uap:Extension>
   <uap3:Extension Category="windows.appExtension">
     <uap3:AppExtension Name="com.microsoft.mathext" Id="sqrt" DisplayName="Sqrt(x)" Description="Square root" PublicFolder="Public">
       <uap3:Properties>
         <Service>com.microsoft.powservice</Service>   <!-- this must match <uap:AppService Name=...> -->
       </uap3:Properties>
     </uap3:AppExtension>
   </uap3:Extension>
</Extensions>   

Elenco di controllo degli scenari di base da testare

Quando si compila un host di estensione e si è pronti a testare il livello di supporto delle estensioni, ecco alcuni scenari di base da provare:

  • Eseguire l'host e quindi distribuire un'app di estensione
    • L'host raccoglie nuove estensioni che vengono eseguite durante l'esecuzione?
  • Distribuire l'app di estensione e quindi distribuire ed eseguire l'host.
    • L'host preleva le estensioni esistenti in precedenza?
  • Eseguire l'host e quindi rimuovere l'app di estensione.
    • L'host rileva correttamente la rimozione?
  • Eseguire l'host e quindi aggiornare l'app di estensione a una versione più recente.
    • L'host preleva la modifica e scarica correttamente le versioni precedenti dell'estensione?

Scenari avanzati da testare:

  • Eseguire l'host, spostare l'app di estensione in supporti rimovibili, rimuovere il supporto
    • L'host rileva la modifica dello stato del pacchetto e disabilita l'estensione?
  • Eseguire l'host, quindi danneggiare l'app di estensione (renderla non valida, firmata in modo diverso e così via)
    • L'host rileva l'estensione manomessa e la gestisce correttamente?
  • Eseguire l'host, quindi distribuire un'app di estensione con contenuto o proprietà non validi
    • L'host rileva il contenuto non valido e lo gestisce correttamente?

Considerazioni relative alla progettazione

  • Fornire l'interfaccia utente che mostra l'utente quali estensioni sono disponibili e consente loro di abilitarle o disabilitarle. È anche possibile prendere in considerazione l'aggiunta di glifi per le estensioni non disponibili perché un pacchetto passa offline e così via.
  • Indirizzare l'utente alla posizione in cui possono ottenere le estensioni. Forse la pagina dell'estensione può fornire una query di ricerca di Microsoft Store che visualizza un elenco di estensioni che possono essere usate con l'app.
  • Si consideri come notificare all'utente l'aggiunta e la rimozione delle estensioni. È possibile creare una notifica per quando viene installata una nuova estensione e invitare l'utente ad abilitarla. Le estensioni devono essere disabilitate per impostazione predefinita in modo che gli utenti siano in controllo.

Differenze tra le estensioni dell'app e i pacchetti facoltativi

Il fattore di differenziazione chiave tra pacchetti facoltativi ed estensioni dell'app è l'ecosistema aperto rispetto all'ecosistema chiuso e il pacchetto dipendente rispetto al pacchetto indipendente.

Le estensioni dell'app partecipano a un ecosistema aperto. Se l'app può ospitare le estensioni dell'app, chiunque può scrivere un'estensione per l'host purché siano conformi al metodo di passaggio/ricezione di informazioni dall'estensione. Ciò differisce dai pacchetti facoltativi che partecipano a un ecosistema chiuso in cui l'editore decide chi può creare un pacchetto facoltativo che può essere usato con l'app.

Le estensioni dell'app sono pacchetti indipendenti e possono essere app autonome. Non possono avere una dipendenza di distribuzione da un'altra app. I pacchetti facoltativi richiedono il pacchetto primario e non possono essere eseguiti senza di esso.

Un pacchetto di espansione per un gioco sarebbe un buon candidato per un pacchetto facoltativo perché è strettamente legato al gioco, non può essere eseguito indipendentemente dal gioco e potrebbe non volere che i pacchetti di espansione vengano creati da qualsiasi sviluppatore nell'ecosistema.

Se lo stesso gioco aveva componenti aggiuntivi o temi personalizzabili dell'interfaccia utente, un'estensione dell'app potrebbe essere una buona scelta perché l'app che fornisce l'estensione potrebbe essere eseguita autonomamente e qualsiasi terza parte potrebbe renderli.

Osservazioni:

Questo argomento fornisce un'introduzione alle estensioni dell'app. Gli aspetti principali da notare sono la creazione dell'host e il contrassegno come tale nel file Package.appxmanifest, la creazione dell'estensione e il contrassegno come tale nel file Package.appxmanifest, la determinazione di come implementare l'estensione (ad esempio un servizio app, attività in background, server COM o WinRT o altri mezzi), definendo il modo in cui l'host comunicherà con le estensioni e utilizzando l'API AppExtensions per accedere e gestire le estensioni.