Concesión de la identidad del paquete mediante el empaquetado con ubicación externa

Si tiene una aplicación de escritorio existente, con su propio instalador, es muy poco necesario cambiar para beneficiarse de la identidad del paquete.

Muchas de las funciones de extensibilidad de Windows, como las tareas en segundo plano, notificaciones, mosaicos en vivo y objetivos compartidos, solo se pueden utilizar con una aplicación de escritorio si esta tiene una identidad del paquete en tiempo de ejecución. Esto se debe a que el sistema operativo (SO) debe ser capaz de identificar al autor de la llamada de la API correspondiente. Consulte Características que requieren la identidad del paquete.

Solo las aplicaciones empaquetadas tienen identidad de paquete en tiempo de ejecución. Para obtener definiciones de aplicaciones empaquetadas, desempaquetadas y empaquetadas con ubicación externa, consulte Información general sobre la implementación.

  • En Windows 10, versión 2004 y versiones anteriores, la única manera de conceder la identidad del paquete a una aplicación es empaquetarlo en un paquete MSIX firmado (consulte Creación de un paquete MSIX a partir del código). En ese caso, la identidad se especifica en el manifiesto de paquete, y el registro de la identidad es manejado por la canalización de implementación de MSIX basado en la información del manifiesto. Todo el contenido al que se hace referencia en el manifiesto del paquete está presente en el paquete MSIX.
  • Pero a partir de Windows 10, versión 2004, puedes conceder la identidad del paquete a una aplicación simplemente compilando y registrando un paquete con la ubicación externa con la aplicación. Si lo hace, se convierte en una aplicación empaquetada; en concreto, una aplicación empaquetada con ubicación externa. Esto se debe a que algunas aplicaciones de escritorio aún no están listas para que todo su contenido esté presente dentro de un paquete MSIX. Por lo tanto, esta compatibilidad permite que estas aplicaciones tengan identidad de paquete; por lo tanto, puede usar características de extensibilidad de Windows que requieren la identidad del paquete. Para más información, consulte la entrada del blog Identidad, registro y activación de aplicaciones Win32 no empaquetadas.

Para compilar y registrar un paquete con ubicación externa (que otorga identidad de paquete a su aplicación), siga estos pasos.

  1. Crear un manifiesto de paquete para el paquete con ubicación externa
  2. Compilar y firmar el paquete con la ubicación externa
  3. Agregar los metadatos de identidad del paquete al manifiesto de aplicación de escritorio
  4. Registro del paquete con una ubicación externa en tiempo de ejecución

Conceptos importantes

Las siguientes funciones permiten que las aplicaciones de escritorio no empaquetadas adquieran la identidad del paquete.

Paquete con ubicación externa

Un paquete con ubicación externa contiene un manifiesto del paquete, pero no otros binarios de la aplicación ni su contenido. El manifiesto de un paquete con ubicación externa puede hacer referencia a archivos fuera del paquete en una ubicación externa predeterminada. Como se mencionó anteriormente, esta compatibilidad permite que las aplicaciones que aún no estén listas para que todo su contenido esté presente dentro de un paquete MSIX para usar las características de extensibilidad de Windows que requieren la identidad del paquete.

Nota

Una aplicación de escritorio que utiliza un paquete con ubicación externa no recibe algunos beneficios de ser desplegada completamente a través de un paquete MSIX. Estas ventajas incluyen la protección contra alteraciones, la instalación en una ubicación bloqueada y la administración completa de la implementación, el tiempo de ejecución y la desinstalación por parte del sistema operativo.

Permitir contenido externo

Para dar soporte a los paquetes con ubicación externa, el esquema del manifiesto del paquete ahora admite un elemento opcional uap10:AllowExternalContent bajo el elemento Properties. Permite que el manifiesto del paquete haga referencia al contenido fuera del paquete, en una ubicación específica en el disco.

Por ejemplo, si tiene su aplicación de escritorio sin empaquetar existente que instala el ejecutable de la aplicación y otros contenidos en C:\NArchivos de programa\NMi aplicación de escritorio, puede crear un paquete con ubicación externa que incluya el elemento uap10:AllowExternalContent en el manifiesto. Durante el proceso de instalación de tu aplicación, o la primera vez que se ejecuta, puedes instalar el paquete con ubicación externa y declarar C:\NArchivos de Programa\NMiApp de Escritorio como la ubicación externa que utilizará tu aplicación.

Crear un manifiesto de paquete para el paquete con ubicación externa

Antes de que pueda compilar un paquete con ubicación externa, debe crear primero un manifiesto de paquete (un archivo llamado AppxManifest.xml) que declare los metadatos de identidad del paquete para su aplicación de escritorio y otros detalles necesarios. La forma más sencilla de crear un manifiesto de paquete con ubicación externa es utilizar el ejemplo siguiente y personalizarlo para su aplicación utilizando la referencia del esquema.

Asegúrate de que el manifiesto del paquete incluye estos elementos:

  • Un elemento Identity que describa los atributos de identidad de la aplicación de escritorio.
  • Un elemento uap10:AllowExternalContent en el elemento Properties. A este elemento se le debe asignar el valor true, que permite que el manifiesto del paquete haga referencia al contenido fuera del paquete, en una ubicación específica en el disco. En un paso posterior, especificará la ruta de la ubicación externa cuando registre su paquete con ubicación externa desde el código que se ejecuta en su instalador o su aplicación. Cualquier contenido al que se haga referencia en el manifiesto que no se encuentre en el propio paquete debe instalarse en la ubicación externa.
  • El atributo MinVersion del elemento TargetDeviceFamily debe establecerse en 10.0.19000.0 o en una versión posterior.
  • Los atributos TrustLevel=mediumIL y RuntimeBehavior=Win32App del elemento Application declaran que la aplicación de escritorio asociada al paquete con ubicación externa se ejecutará de forma similar a una aplicación de escritorio estándar sin empaquetar, sin virtualización del registro y del sistema de archivos ni otros cambios en tiempo de ejecución.

El siguiente ejemplo muestra el contenido completo de un paquete con manifiesto de ubicación externa (AppxManifest.xml). Este manifiesto incluye una extensión windows.sharetarget, que requiere la identidad del paquete.

<?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>

Compilar y firmar el paquete con la ubicación externa

Después de crear el manifiesto del paquete, compile el paquete con ubicación externa utilizando la herramienta MakeAppx.exe del SDK de Windows. Como el paquete con ubicación externa no contiene los archivos a los que se hace referencia en el manifiesto, debe especificar la opción /nv, que omite la validación semántica del paquete.

El siguiente ejemplo demuestra cómo crear un paquete con ubicación externa desde la línea de comandos.

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

Antes de que su paquete con ubicación externa pueda instalarse correctamente en un ordenador de destino, debe firmarlo con un certificado que sea de confianza en el ordenador de destino. Puede crear un nuevo certificado autofirmado para fines de desarrollo y firmar su paquete con una ubicación externa utilizando SignTool, que está disponible en el SDK de Windows.

El siguiente ejemplo demuestra cómo firmar un paquete con ubicación externa desde la línea de comandos.

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

Agregar los metadatos de identidad del paquete al manifiesto de aplicación de escritorio

También debe incluir un manifiesto de la aplicación junto con su aplicación de escritorio. Consulte Manifiestos de aplicación (es el archivo que declara elementos como el reconocimiento de PPP y se inserta en .exe de la aplicación durante la compilación). En ese archivo, incluya un elemento msix con atributos que declaren los atributos de identidad de la aplicación. El sistema operativo usa los valores de estos atributos para determinar la identidad de la aplicación cuando se inicia el archivo ejecutable.

En el ejemplo siguiente se muestra un manifiesto de la aplicación en paralelo 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>

Los atributos del elemento msix deben coincidir con estos valores en el manifiesto del paquete con ubicación externa:

  • Los atributos packageName y publisher deben coincidir con los atributos Name y Publisher del elemento Identity del manifiesto del paquete, respectivamente.
  • El atributo applicationId debe coincidir con el atributo Id del elemento Application del manifiesto del paquete.

Registro del paquete con una ubicación externa en tiempo de ejecución

Para conceder la identidad del paquete a su aplicación de escritorio, su aplicación debe registrar el paquete con la ubicación externa mediante el método AddPackageByUriAsync de la clase PackageManager. Este método está disponible a partir de Windows 10, versión 2004. Puedes agregar código a la aplicación para registrar el paquete con la ubicación externa cuando se ejecuta la aplicación por primera vez, o puedes ejecutar código para registrar el paquete mientras se instala la aplicación de escritorio (por ejemplo, si utiliza MSI para instalar la aplicación de escritorio, puede ejecutar este código desde una acción personalizada).

En el ejemplo siguiente se muestra cómo registrar un paquete con una ubicación externa. Este código crea un objeto AddPackageOptions que contiene la ruta de acceso a la ubicación externa donde el manifiesto del paquete puede hacer referencia al contenido fuera del paquete. Luego, el código pasa este objeto al método AddPackageByUriAsync para registrar el paquete con ubicación externa. Este método también recibe la ubicación de su paquete firmado con ubicación externa como URI. Para obtener un ejemplo más completo, consulte el archivo de código StartUp.cs de la aplicación de ejemplo relacionada (consulte la sección Aplicación de ejemplo de este tema).

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

Aplicación de ejemplo

Consulte la muestra SparsePackages (paquetes con ubicación externa) para obtener una aplicación de ejemplo totalmente funcional que muestre cómo conceder la identidad del paquete a una aplicación de escritorio mediante un paquete con ubicación externa. En el tutorial de este tema se resaltan los pasos clave para conceder la identidad del paquete a una aplicación sin empaquetar, pero la aplicación de ejemplo proporciona un ejemplo completo que puede usar como referencia. En la entrada del blog Identidad, registro y activación de aplicaciones Win32 no empaquetadas se ofrece más información sobre la creación y ejecución de la muestra.

En este ejemplo se incluye lo siguiente:

  • El código fuente de una aplicación de WPF denominada PhotoStoreDemo. Durante el inicio, la aplicación comprueba si se está ejecutando con identidad. Si no se está ejecutando con identidad, registra el paquete con ubicación externa, y luego reinicia la aplicación. Consulta en StartUp.cs el código que realiza estos pasos.
  • Un manifiesto de aplicación en paralelo denominado PhotoStoreDemo.exe.manifest.
  • Un manifiesto de paquete denominado AppxManifest.xml.