Concedere l'identità del pacchetto tramite creazione di pacchetti con posizione esterna

Se si dispone di un'app desktop esistente dotata di programma di installazione proprio, le modifiche da apportare per trarre vantaggio da questa identità del pacchetto sono minime.

Molte funzionalità di estensibilità di Windows, tra cui attività in background, notifiche, riquadri animati, estensioni del menu contestuale personalizzate e destinazioni di condivisione, possono essere usate da un'app desktop solo se tale app dispone dell'identità del pacchetto in fase di esecuzione. Questo perché il sistema operativo (OS) deve essere in grado di identificare il chiamante dell'API corrispondente. Vedere Funzionalità che richiedono l'identità del pacchetto.

Solo le app incluse in pacchetto dispongono di un’identità del pacchetto in fase di esecuzione. Per le definizioni di app in pacchetto, non in pacchetto e in pacchetto con la posizione esterna, consulta Panoramica della distribuzione.

  • In Windows 10, versione 2004 e versioni precedenti, l'unico modo per concedere l'identità del pacchetto a un'app consiste nel creare un pacchetto MSIX firmato (vedere Creazione di un pacchetto MSIX dal codice). In tal caso, l'identità viene specificata nel manifesto del pacchetto e la registrazione dell'identità viene gestita dalla pipeline di distribuzione MSIX in base alle informazioni contenute nel manifesto. Tutto il contenuto a cui si fa riferimento nel manifesto del pacchetto è presente all'interno del pacchetto MSIX.
  • Tuttavia, a partire da Windows 10, versione 2004, è possibile concedere l'identità del pacchetto a un'app semplicemente creando e registrando un pacchetto con posizione esterna con l'app. In questo modo lo trasforma in un'app in pacchetto; in particolare, un'app in pacchetto con posizione esterna. Questo perché alcune app per desktop non sono ancora pronte a contenere tutti i loro contenuti all'interno di un pacchetto MSIX. Pertanto, questo supporto consente a tali applicazioni di disporre di un'identità del pacchetto, in modo da poter usare le funzioni di estendibilità di Windows che richiedono l'identità del pacchetto. Per altre informazioni generali, vedere il post di blog Identità, registrazione e attivazione di appWin32 non in pacchetto.

Per compilare e registrare un pacchetto con posizione esterna, che concede l'identità del pacchetto all'app, seguire la procedura seguente.

  1. Creare un manifesto del pacchetto per il pacchetto con posizione esterna
  2. Compilare e firmare il pacchetto con posizione esterna
  3. Aggiungere i metadati di identità del pacchetto al manifesto dell'applicazione desktop
  4. Registrare il pacchetto con posizione esterna in fase di esecuzione

Concetti importanti

Le funzionalità seguenti consentono alle app desktop non in pacchetto di acquisire l'identità del pacchetto.

Pacchetto con posizione esterna

Un pacchetto con posizione esterna contiene un manifesto del pacchetto, ma nessun altro file binario e contenuto dell'app. Il manifesto di un pacchetto con posizione esterna può fare riferimento a file esterni al pacchetto in una posizione esterna predeterminata. Come accennato in precedenza, questo supporto consente alle app che non sono ancora pronte per tutti i contenuti di essere presenti all'interno di un pacchetto MSIX per usare le funzionalità di estendibilità di Windows che richiedono l'identità del pacchetto.

Nota

Un'app desktop che usa un pacchetto con posizione esterna non riceve alcuni vantaggi derivanti dalla distribuzione completa tramite un pacchetto MSIX. Questi vantaggi includono la protezione antimanomissione, l'installazione in un percorso bloccato e la gestione completa da parte del sistema operativo in fase di distribuzione, esecuzione e disinstallazione.

Consenti contenuto esterno

Per supportare i pacchetti con posizione esterna, lo schema del manifesto del pacchetto supporta ora un elemento uap10:AllowExternalContent facoltativo nell'elemento Properties. In questo modo il manifesto del pacchetto può fare riferimento al contenuto all'esterno del pacchetto, in un percorso specifico sul disco.

Ad esempio, se si dispone di un'app desktop esistente non in pacchetto che installa gli elementi eseguibili e altri contenuti in C:\Program Files\MyDesktopApp, è possibile creare un pacchetto con posizione esterna che includa l'elemento uap10:AllowExternalContent nel manifesto. Durante il processo di installazione dell'app, o la prima volta che l'app si apre, è possibile installare il pacchetto con posizione esterna e dichiarare C:\Program Files\MyDesktopApp\ come posizione esterna usata dall'app.

Creare un manifesto del pacchetto per il pacchetto con posizione esterna

Prima di poter compilare un pacchetto con posizione esterna, è necessario creare un manifesto del pacchetto, ovvero un file denominato AppxManifest.xml, che dichiari i metadati dell'identità del pacchetto per l'app desktop e altri dettagli necessari. Il modo più semplice per creare un manifesto del pacchetto per il pacchetto con posizione esterna consiste nell'usare l'esempio seguente e personalizzarlo per l'app usando il riferimento dello schema.

Verifica che il manifesto del pacchetto includa questi elementi:

  • Un elemento Identity che descrive gli attributi di identità per l'app desktop.
  • Un elemento uap10:AllowExternalContent nell'elemento Properties. A questo elemento deve essere assegnato il valore true, in questo modo il manifesto del pacchetto può fare riferimento al contenuto all'esterno del pacchetto, in un percorso specifico sul disco. In un passaggio successivo, si specificherà il percorso della posizione esterna quando si registrerà il pacchetto con posizione esterna a partire dal codice eseguito nel programma di installazione o nell'app. Qualsiasi contenuto a cui si fa riferimento nel manifesto che non si trova nel pacchetto stesso deve essere installato nella posizione esterna.
  • L'attributo MinVersion dell'elemento TargetDeviceFamily deve essere impostato su 10.0.19000.0 o una versione successiva.
  • Gli attributi TrustLevel=mediumIL e RuntimeBehavior=Win32App dell'elemento Application dichiarano che l'app desktop associata al pacchetto con posizione esterna verrà eseguita in modo simile a un'app desktop standard non in pacchetto, evitando la virtualizzazione del Registro di sistema e del file system e altre modifiche in fase di esecuzione.

L'esempio seguente mostra il contenuto completo di un pacchetto con manifesto della posizione esterna (AppxManifest.xml). Questo manifesto include un'estensione windows.sharetarget, che richiede l'identità del pacchetto.

<?xml version="1.0" encoding="utf-8"?>
<Package 
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
  xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
  IgnorableNamespaces="uap uap2 uap3 rescap desktop uap10">
  <Identity Name="ContosoPhotoStore" ProcessorArchitecture="x64" Publisher="CN=Contoso" Version="1.0.0.0" />
  <Properties>
    <DisplayName>ContosoPhotoStore</DisplayName>
    <PublisherDisplayName>Contoso</PublisherDisplayName>
    <Logo>Assets\storelogo.png</Logo>
    <uap10:AllowExternalContent>true</uap10:AllowExternalContent>
  </Properties>
  <Resources>
    <Resource Language="en-us" />
  </Resources>
  <Dependencies>
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19000.0" MaxVersionTested="10.0.19000.0" />
  </Dependencies>
  <Capabilities>
    <rescap:Capability Name="runFullTrust" />
    <rescap:Capability Name="unvirtualizedResources"/>
  </Capabilities>
  <Applications>
    <Application Id="ContosoPhotoStore" Executable="ContosoPhotoStore.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App"> 
      <uap:VisualElements AppListEntry="none" DisplayName="Contoso PhotoStore" Description="Demonstrate photo app" BackgroundColor="transparent" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png">
        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png"></uap:DefaultTile>
        <uap:SplashScreen Image="Assets\SplashScreen.png" />
      </uap:VisualElements>
      <Extensions>
        <uap:Extension Category="windows.shareTarget">
          <uap:ShareTarget Description="Send to ContosoPhotoStore">
            <uap:SupportedFileTypes>
              <uap:FileType>.jpg</uap:FileType>
              <uap:FileType>.png</uap:FileType>
              <uap:FileType>.gif</uap:FileType>
            </uap:SupportedFileTypes>
            <uap:DataFormat>StorageItems</uap:DataFormat>
            <uap:DataFormat>Bitmap</uap:DataFormat>
          </uap:ShareTarget>
        </uap:Extension>
      </Extensions>
    </Application>
  </Applications>
</Package>

Compilare e firmare il pacchetto con posizione esterna

Dopo aver creato il manifesto del pacchetto, compilare il pacchetto con posizione esterna usando lo strumento MakeAppx.exe in Windows SDK. Poiché il pacchetto con posizione esterna non contiene i file a cui si fa riferimento nel manifesto, è necessario specificare l'opzione /nv, che consente di ignorare la convalida semantica per il pacchetto.

Nell'esempio seguente viene illustrato come creare un pacchetto con un posizione esterna dalla riga di comando.

MakeAppx.exe pack /d <path to directory that contains manifest> /p <output path>\MyPackage.msix /nv

Prima che il pacchetto con posizione esterna possa essere installato correttamente in un computer di destinazione, è necessario firmarlo con un certificato attendibile nel computer di destinazione. È possibile creare un nuovo certificato autofirmato per scopi di sviluppo e firmare il pacchetto con posizione esterna usando SignTool, disponibile in Windows SDK.

Nell'esempio seguente viene illustrato come firmare un pacchetto con posizione esterna dalla riga di comando.

SignTool.exe sign /fd SHA256 /a /f <path to certificate>\MyCertificate.pfx /p <certificate password> <path to package with external location>\MyPackage.msix

Aggiungere i metadati di identità del pacchetto al manifesto dell'applicazione desktop

È anche necessario includere un manifesto dell'applicazione affiancato all'app desktop. Vedere Manifesto dell'applicazione, ovvero un file che dichiara elementi come la riconoscimento DPI e viene incorporato nell'applicazione .exe durante la compilazione. In tale file, includere un elemento msix con attributi che dichiarino gli attributi di identità dell'app. I valori di questi attributi vengono usati dal sistema operativo per determinare l'identità dell'app quando viene avviato l'eseguibile.

L'esempio seguente illustra un manifesto dell'applicazione affiancato con un elemento msix.

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="Contoso.PhotoStoreApp"/>
  <msix xmlns="urn:schemas-microsoft-com:msix.v1"
          publisher="CN=Contoso"
          packageName="ContosoPhotoStore"
          applicationId="ContosoPhotoStore"
        />
</assembly>

Gli attributi dell'elemento msix devono corrispondere ai valori seguenti nel manifesto del pacchetto con posizione esterna:

  • Gli attributi packageName e publisher devono corrispondere rispettivamente agli attributi Name e Publisher dell'elemento Identity nel manifesto del pacchetto.
  • L'attributoapplicationId deve corrispondere all'attributo Id dell'elemento Application del manifesto del pacchetto.

Registrare il pacchetto con posizione esterna in fase di esecuzione

Per concedere l'identità del pacchetto all'app desktop, è necessario che l'app registri il pacchetto con posizione esterna, usando il metodo AddPackageByUriAsync della classe PackageManager. Questo metodo è disponibile a partire da Windows 10, versione 2004. È possibile aggiungere codice all'app per registrare il pacchetto con posizione esterna quando l'app viene eseguita per la prima volta, oppure è possibile eseguire il codice per registrare il pacchetto durante l'installazione dell'app desktop (ad esempio, se si utilizza MSI per installare l'app desktop, è possibile eseguire questo codice da un'azione personalizzata).

Nell'esempio seguente viene illustrato come registrare un pacchetto con posizione esterna. Questo codice crea un oggetto AddPackageOptions che contiene il percorso verso la posizione esterna dove il manifesto del pacchetto può fare riferimento al contenuto al di fuori del pacchetto. Il codice passa quindi questo oggetto al metodo AddPackageByUriAsync per registrare il pacchetto con posizione esterna. Tale metodo riceve anche la posizione del pacchetto firmato con la posizione esterna come URI. Per un esempio più completo, vedere il StartUp.cs file di codice nell'app di esempio correlata (vedere la sezione App di esempio in questo argomento).

private static bool registerPackageWithExternalLocation(string externalLocation, string pkgPath)
{
    bool registration = false;
    try
    {
        Uri externalUri = new Uri(externalLocation);
        Uri packageUri = new Uri(pkgPath);

        Console.WriteLine("exe Location {0}", externalLocation);
        Console.WriteLine("msix Address {0}", pkgPath);

        Console.WriteLine("  exe Uri {0}", externalUri);
        Console.WriteLine("  msix Uri {0}", packageUri);

        PackageManager packageManager = new PackageManager();

        // Declare use of an external location
        var options = new AddPackageOptions();
        options.ExternalLocationUri = externalUri;

        Windows.Foundation.IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress> deploymentOperation = packageManager.AddPackageByUriAsync(packageUri, options);

        // Other progress and error-handling code omitted for brevity...
    }
}

Esempio di app

Per un'app di esempio completamente funzionante che illustra come concedere l'identità del pacchetto a un'app desktop usando un pacchetto con posizione esterna, vedere l'esempio SparsePackages. Altre informazioni sulla compilazione e l'esecuzione dell'esempio sono disponibili nel post di blog Identità, registrazione e attivazione di app Win32 non in pacchetto.

Questo esempio include quanto segue:

  • Codice sorgente per un'app WPF denominata PhotoStoreDemo. Durante l'avvio, l'app verifica se è in esecuzione con identità. Se non è in esecuzione con identità, registrare il pacchetto con la posizione esterna e quindi riavviare l'app. Vedi StartUp.cs per il codice che esegue questi passaggi.
  • Un manifesto dell'applicazione affiancato denominato PhotoStoreDemo.exe.manifest.
  • Un manifesto del pacchetto denominato AppxManifest.xml.