Concedere l'identità ad app desktop non in pacchettoGrant identity to non-packaged desktop apps

Molte funzionalità di estensibilità di Windows 10 richiedono identità del pacchetto per essere usate da applicazioni desktop non UWP, incluse le attività in background, le notifiche, i riquadri animati e le destinazioni di condivisione.Many Windows 10 extensibility features require package identity to be used from non-UWP desktop apps, including background tasks, notifications, live tiles, and share targets. Per questi scenari, il sistema operativo richiede l'identità, in modo che possa identificare il chiamante dell'API corrispondente.For these scenarios, the OS requires identity so that it can identify the caller of the corresponding API.

Nelle versioni del sistema operativo precedenti a Windows 10, versione 2004, l'unico modo per concedere l'identità a un'app desktop consiste nell'inserirla in un pacchetto MSIX firmato.In OS releases before Windows 10, version 2004, the only way to grant identity to a desktop app is to package it in a signed MSIX package. Per queste app, 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.For these apps, identity is specified in the package manifest and identity registration is handled by the MSIX deployment pipeline based on the information in the manifest. Tutto il contenuto a cui si fa riferimento nel manifesto del pacchetto è presente all'interno del pacchetto MSIX.All content referenced in the package manifest is present inside the MSIX package.

A partire da Windows 10, versione 2004, è possibile concedere l'identità del pacchetto alle app desktop che non sono inserite in un pacchetto MSIX compilando e registrando un pacchetto sparse con l'app.Starting in Windows 10, version 2004, you can grant package identity to desktop apps that are not packaged in an MSIX package by building and registering a sparse package with your app. Questo supporto consente alle app desktop che non sono ancora in grado di adottare la creazione di pacchetti MSIX per la distribuzione di usare le funzionalità di estendibilità di Windows 10 che richiedono l'identità del pacchetto.This support enables desktop apps that are not yet able to adopt MSIX packaging for deployment to use Windows 10 extensibility features that require package identity. Per altre informazioni di background, vedi questo post di blog.For more background info, see this blog post.

Per compilare e registrare un pacchetto sparse che concede l'identità del pacchetto all'app desktop, segui questa procedura.To build and register a sparse package that grants package identity to your desktop app, follow these steps.

  1. Creare un manifesto del pacchetto per il pacchetto sparseCreate a package manifest for the sparse package
  2. Compilare e firmare il pacchetto sparseBuild and sign the sparse package
  3. Aggiungere i metadati di identità del pacchetto al manifesto dell'applicazione desktopAdd the package identity metadata to your desktop application manifest
  4. Registrare il pacchetto sparse in fase di esecuzioneRegister your sparse package at run time

Concetti importantiImportant concepts

Le funzionalità seguenti consentono alle app desktop non in pacchetto di acquisire l'identità del pacchetto.The following features enable non-packaged desktop apps to acquire package identity.

Pacchetti sparseSparse packages

Un pacchetto sparse contiene un manifesto del pacchetto, ma non altri file binari e contenuto dell'app.A sparse package contains a package manifest but no other app binaries and content. Il manifesto di un pacchetto sparse può fare riferimento a file esterni al pacchetto in una posizione esterna predeterminata.The manifest of a sparse package can reference files outside the package in a predetermined external location. Ciò consente alle applicazioni che non sono ancora in grado di adottare la creazione di pacchetti MSIX per l'intera app di acquisire l'identità del pacchetto come richiesto da alcune funzionalità di estendibilità di Windows 10.This allows applications that are not yet able to adopt MSIX packaging for their entire app to acquire package identity as required by some Windows 10 extensibility features.

Nota

Un'app desktop che usa un pacchetto sparse non riceve alcuni vantaggi derivanti dalla distribuzione completa tramite un pacchetto MSIX.A desktop app that uses a sparse package does not receive some benefits of being fully deployed via an MSIX package. 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.These benefits include tamper protection, installation in a locked-down location, and full management by the OS at deployment, run time, and uninstall.

Percorso esterno del pacchettoPackage external location

Per supportare i pacchetti sparse, lo schema del manifesto del pacchetto supporta ora un elemento uap10:AllowExternalContent facoltativo nell'elemento Properties.To support sparse packages, the package manifest schema now supports an optional uap10:AllowExternalContent element under the Properties element. In questo modo il manifesto del pacchetto può fare riferimento al contenuto all'esterno del pacchetto, in un percorso specifico sul disco.This allows your package manifest to reference content outside the package, in a specific location on disk.

Ad esempio, se hai un'app desktop non in pacchetto che installa l'eseguibile dell'applicazione e altro contenuto in C:\Program Files\MyDesktopApp,, puoi creare un pacchetto sparse che includa l'elemento uap10:AllowExternalContent nel manifesto.For example, if you have your existing non-packaged desktop app that installs the app executable and other content in C:\Program Files\MyDesktopApp, you can create a sparse package that includes the uap10:AllowExternalContent element in the manifest. Durante il processo di installazione dell'app o la prima volta che apri l'app, puoi installare il pacchetto sparse e dichiarare C:\Program Files\MyDesktopApp\ come il percorso esterno usato dall'app.During the install process for your app or the first time your apps, you can install the sparse package and declare C:\Program Files\MyDesktopApp\ as the external location your app will use.

Creare un manifesto del pacchetto per il pacchetto sparseCreate a package manifest for the sparse package

Prima di poter compilare un pacchetto sparse, devi creare prima di tutto un manifesto del pacchetto (un file denominato AppxManifest.xml) che dichiara i metadati dell'identità del pacchetto per l'app desktop e altri dettagli necessari.Before you can build a sparse package, you must first create a package manifest (a file named AppxManifest.xml) that declares package identity metadata for your desktop app and other required details. Il modo più semplice per creare un manifesto del pacchetto per il pacchetto sparse consiste nell'usare l'esempio seguente e personalizzarlo per l'app usando il riferimento dello schema.The easiest way to create a package manifest for the sparse package is to use the example below and customize it for your app by using the schema reference.

Verifica che il manifesto del pacchetto includa questi elementi:Make sure the package manifest includes these items:

  • Un elemento Identity che descrive gli attributi di identità per l'app desktop.An Identity element that describes the identity attributes for your desktop app.
  • Un elemento uap10:AllowExternalContent nell'elemento Properties.An uap10:AllowExternalContent element under the Properties element. 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.This element should be assigned the value true, which allows your package manifest to reference content outside the package, in a specific location on disk. In una fase successiva, specificherai il percorso della posizione esterna quando registri il pacchetto sparse dal codice eseguito nel programma di installazione o nell'app.In a later step, you'll specify the path of the external location when you register your sparse package from code that runs in your installer or your app. Qualsiasi contenuto a cui si fa riferimento nel manifesto che non si trova nel pacchetto stesso deve essere installato nella posizione esterna.Any content that you reference in the manifest that isn’t located in the package itself should be installed to the external location.
  • L'attributo MinVersion dell'elemento TargetDeviceFamily deve essere impostato su 10.0.19000.0 o una versione successiva.The MinVersion attribute of the TargetDeviceFamily element should be set to 10.0.19000.0 or a later version.
  • Gli attributi TrustLevel=mediumIL e RuntimeBehavior=Win32App dell'elemento Application dichiarano che l'app desktop associata al pacchetto sparse viene eseguita in modo analogo a un'app desktop standard non in pacchetto, senza virtualizzazione del Registro di sistema e del file system e altre modifiche in fase di esecuzione.The TrustLevel=mediumIL and RuntimeBehavior=Win32App attributes of the Application element declare that the desktop app associated with the sparse package will run similar to a standard unpackaged desktop app, without registry and file system virtualization and other run time changes.

Nell'esempio seguente viene illustrato il contenuto completo di un manifesto del pacchetto sparse (AppxManifest.xml).The following example shows the complete contents of a sparse package manifest (AppxManifest.xml). Questo manifesto include un'estensione windows.sharetarget, che richiede l'identità del pacchetto.This manifest includes a windows.sharetarget extension, which requires package identity.

<?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 sparseBuild and sign the sparse package

Dopo aver creato il manifesto del pacchetto, compilare il pacchetto sparse usando lo strumento MakeAppx.exe in Windows SDK.After you create your package manifest, build the sparse package by using the MakeAppx.exe tool in the Windows SDK. Poiché il pacchetto sparse 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.Because the sparse package doesn’t contain the files referenced in the manifest, you must specify the /nv option, which skips semantic validation for the package.

Nell'esempio seguente viene illustrato come creare un pacchetto sparse dalla riga di comando.The following example demonstrates how to create a sparse package from the command line.

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

Prima che il pacchetto sparse possa essere installato correttamente in un computer di destinazione, devi firmarlo con un certificato attendibile nel computer di destinazione.Before your sparse package can be successfully installed on a target computer, you must sign it with a certificate that is trusted on the target computer. Puoi creare un nuovo certificato autofirmato per scopi di sviluppo e firmare il pacchetto sparse usando SignTool, disponibile in Windows SDK.You can create a new self-signed certificate for development purposes and sign your sparse package using SignTool, which is available in the Windows SDK.

Nell'esempio seguente viene illustrato come firmare un pacchetto sparse dalla riga di comando.The following example demonstrates how to sign a sparse package from the command line.

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

Aggiungere i metadati di identità del pacchetto al manifesto dell'applicazione desktopAdd the package identity metadata to your desktop application manifest

È inoltre necessario includere un manifesto dell'applicazione affiancato con l'app desktop e includere un elemento msix con attributi che dichiarano gli attributi di identità dell'app.You must also include a side-by-side application manifest with your desktop app and include an msix element with attributes that declare the identity attributes of your app. I valori di questi attributi vengono usati dal sistema operativo per determinare l'identità dell'app quando viene avviato l'eseguibile.The values of these attributes are used by the OS to determine your app's identity when the executable is launched.

L'esempio seguente illustra un manifesto dell'applicazione affiancato con un elemento msix.The following example shows a side-by-side application manifest with an msix element.

<?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 sparse:The attributes of the msix element must match these values in the package manifest for your sparse package:

  • Gli attributi packageName e publisher devono corrispondere rispettivamente agli attributi Name e Publisher dell'elemento Identity nel manifesto del pacchetto.The packageName and publisher attributes must match the Name and Publisher attributes in the Identity element in your package manifest, respectively.
  • L'attributo applicationId deve corrispondere all'attributo Id dell'elemento Application del manifesto del pacchetto.The applicationId attribute must match the Id attribute of the Application element in your package manifest.

Il manifesto dell'applicazione affiancato deve trovarsi nella stessa directory del file eseguibile dell'app desktop e, per convenzione, deve avere lo stesso nome del file eseguibile dell'app con l'estensione .manifest aggiunta ad esso.The side-by-side application manifest must exist in the same directory as the executable file for your desktop app, and by convention it should have the same name as your app's executable file with the .manifest extension appended to it. Ad esempio, se il nome dell'eseguibile dell'app è ContosoPhotoStore, il nome file del manifesto dell'applicazione deve essere ContosoPhotoStore.exe.manifest.For example, if your app's executable name is ContosoPhotoStore, the application manifest filename should be ContosoPhotoStore.exe.manifest.

Registrare il pacchetto sparse in fase di esecuzioneRegister your sparse package at run time

Per concedere l'identità del pacchetto all'app desktop, l'app deve registrare il pacchetto sparse usando il metodo AddPackageByUriAsync della classe PackageManager.To grant package identity to your desktop app, your app must register the sparse package by using the AddPackageByUriAsync method of the PackageManager class. Questo metodo è disponibile a partire da Windows 10, versione 2004.This method is available starting in Windows 10, version 2004. Puoi aggiungere codice all'app per registrare il pacchetto sparse quando l'app viene eseguita per la prima volta oppure puoi eseguire il codice per registrare il pacchetto mentre è installata l'app desktop (ad esempio, se usi l'identità del servizio gestito per installare l'app desktop, puoi eseguire questo codice da un'azione personalizzata).You can add code to your app to register the sparse package when your app is run for the first time, or you can run code to register the package while your desktop app is installed (for example, if you're using MSI to install your desktop app, you can run this code from a custom action).

Nell'esempio seguente viene illustrato come registrare un pacchetto sparse.The following example demonstrates how to register a sparse package. 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.This code creates an AddPackageOptions object that contains the path to the external location where your package manifest can reference content outside the package. Il codice passa quindi questo oggetto al metodo AddPackageByUriAsync per registrare il pacchetto sparse.Then, the code passes this object to the AddPackageByUriAsync method to register the sparse package. Questo metodo riceve anche il percorso del pacchetto sparse firmato come URI.This method also receives the location of your signed sparse package as a URI. Per un esempio più completo, vedi il file di codice StartUp.cs nel relativo campione.For a more complete example, see the StartUp.cs code file in the related sample.

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

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

        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...
    }
}

EsempioSample

Per un'app di esempio completamente funzionante che illustra come concedere l'identità del pacchetto a un'app desktop usando un pacchetto sparse, vedi l'esempio SparesePackages.See the SparesePackages sample for a fully functional sample app that demonstrates how to grant package identity to a desktop app using a sparse package. Altre informazioni sulla compilazione e sull'esecuzione dell'esempio sono disponibili in questo post di blog.More information about building and running the sample is provided in this blog post.

Questo esempio include quanto segue:This sample includes the following:

  • Codice sorgente per un'app WPF denominata PhotoStoreDemo.The source code for a WPF app named PhotoStoreDemo. Durante l'avvio, l'app verifica se è in esecuzione con identità.During startup, the app checks to see whether it is running with identity. Se non è in esecuzione con identità, registra il pacchetto sparse e quindi riavvia l'app.If it is not running with identity, it registers the sparse package and then restarts the app. Vedi StartUp.cs per il codice che esegue questi passaggi.See StartUp.cs for the code that performs these steps.
  • Un manifesto dell'applicazione affiancato denominato PhotoStoreDemo.exe.manifest.A side-by-side application manifest named PhotoStoreDemo.exe.manifest.
  • Un manifesto del pacchetto denominato AppxManifest.xml.A package manifest named AppxManifest.xml.