Detectar la identidad del paquete y el contexto en tiempo de ejecución

Puede que tengas algunas versiones de la aplicación que no se distribuyeron en un paquete MSIX. En tiempo de ejecución, la aplicación puede detectar si se implementó como paquete MSIX mediante la API del Administrador de paquetes de Windows o tu propio instalador personalizado. Puede que quieras cambiar el comportamiento de la aplicación, como la configuración de actualización, o aprovechar las ventajas de una funcionalidad que solo está disponible para los paquetes MSIX.

Para determinar si la aplicación se ejecuta como un paquete MSIX en una versión de Windows que admite el conjunto completo de características de MSIX, puedes usar la función nativa GetCurrentPackageFullName en kernel32.dll. Cuando una aplicación de escritorio se ejecuta como una aplicación no empaquetada sin identidad de paquete, esta función devuelve un error que puede ayudarte a deducir el contexto en el que se ejecuta la aplicación.

Si la función se realiza correctamente, significa que:

  • La aplicación está empaquetada en un paquete MSIX.
  • La aplicación se ejecuta en Windows 10, versión 1709 (compilación 16299) o posterior con compatibilidad completa con MSIX.

Uso de GetCurrentPackageFullName en código nativo

En el ejemplo de código siguiente se muestra cómo usar GetCurrentPackageFullName para determinar el contexto de una aplicación.

#define _UNICODE 1
#define UNICODE 1

#include <Windows.h>
#include <appmodel.h>
#include <malloc.h>
#include <stdio.h>

int __cdecl wmain()
{
    UINT32 length = 0;
    LONG rc = GetCurrentPackageFullName(&length, NULL);
    if (rc != ERROR_INSUFFICIENT_BUFFER)
    {
        if (rc == APPMODEL_ERROR_NO_PACKAGE)
            wprintf(L"Process has no package identity\n");
        else
            wprintf(L"Error %d in GetCurrentPackageFullName\n", rc);
        return 1;
    }

    PWSTR fullName = (PWSTR) malloc(length * sizeof(*fullName));
    if (fullName == NULL)
    {
        wprintf(L"Error allocating memory\n");
        return 2;
    }

    rc = GetCurrentPackageFullName(&length, fullName);
    if (rc != ERROR_SUCCESS)
    {
        wprintf(L"Error %d retrieving PackageFullName\n", rc);
        return 3;
    }
    wprintf(L"%s\n", fullName);

    free(fullName);

    return 0;
}

Uso de la función GetCurrentPackageFullName en código administrado

Para llamar a GetCurrentPackageFullName en una aplicación de .NET Framework administrada, tienes que usar Invocación de plataforma (P/Invoke) o alguna otra forma de interoperabilidad.

Para simplificar este proceso, puedes usar la biblioteca DesktopBridgeHelpers. Esta biblioteca admite .NET Framework 4 y versiones posteriores, y usa internamente P/Invoke para proporcionar una clase auxiliar que determina si la aplicación se ejecuta en una versión de Windows que admite el conjunto completo de características de MSIX. Esta biblioteca también está disponible como paquete NuGet.

Después de instalar el paquete en el proyecto, puedes crear una nueva instancia de la clase DesktopBridge.Helpers y llamar al método IsRunningAsUwp. Este método devuelve true si la aplicación se ejecuta como un paquete MSIX en Windows 10, versión 1709 (compilación 16299) o posterior, y false si alguno de estos datos no es cierto. En el ejemplo siguiente se muestra cómo llamar a este método.

private bool IsRunningAsUwp()
{
   UwpHelpers helpers = new UwpHelpers();
   return helpers.IsRunningAsUwp();
}

private void Form1_Load(object sender, EventArgs e)
{
   if (IsRunningAsUwp())
   {
       txtUwp.Text = "I'm running as MSIX";
   }
   else
   {
       txtUwp.Text = "I'm running as a native desktop app";
   }
}