Détecter l’identité du package et le contexte d’exécution

Un processus est empaqueté lorsqu’il possède une identité de package. Un processus est non empaqueté lorsqu’il ne possède pas d’identité de package. Cette distinction s’applique aux processus plutôt qu’aux applications, car les tâches en arrière-plan, les serveurs hors processus et d’autres processus peuvent également avoir une identité de package.

L’identité de package peut provenir d’un package qui contient les fichiers d’application ou d’un package avec un emplacement externe. Par conséquent, la détection de l’identité du package ne vous indique pas où les fichiers d’application sont stockés ou quel modèle d’empaquetage l’application utilise.

Une application peut vérifier son identité d’exécution avant d’utiliser une fonctionnalité qui nécessite une identité de package, de sélectionner un mécanisme de mise à jour ou de choisir un emplacement de stockage.

Vérifier un processus dans le Gestionnaire des tâches

Vous pouvez inspecter un processus en cours d’exécution sans modifier l’application :

  1. Ouvrez le Gestionnaire des tâches et sélectionnez Détails.
  2. Cliquez avec le bouton droit sur un en-tête de colonne, puis sélectionnez Sélectionner des colonnes.
  3. Sélectionnez Nom du package, puis sélectionnez OK.

Le champ Nom du package est vide pour un processus non empaqueté. Pour un processus empaqueté, il contient normalement le nom d’affichage localisé du package. Les noms d’affichage ne sont pas garantis comme uniques. Si le Gestionnaire des tâches ne peut pas résoudre la ressource localisée, il peut afficher une ms-resource: référence à la place.

Utiliser GetCurrentPackageFullName dans le code natif

Appelez GetCurrentPackageFullName sans tampon :

  • ERROR_INSUFFICIENT_BUFFER signifie que le processus a une identité de package.
  • APPMODEL_ERROR_NO_PACKAGE signifie que le processus n’a pas d’identité de package.
  • Toute autre valeur est une erreur que votre application doit gérer.
#include <Windows.h>
#include <appmodel.h>

LONG IsPackagedProcess(bool* isPackaged)
{
    if (isPackaged == nullptr)
    {
        return ERROR_INVALID_PARAMETER;
    }

    *isPackaged = false;
    UINT32 length = 0;
    const LONG result = GetCurrentPackageFullName(&length, nullptr);

    if (result == ERROR_INSUFFICIENT_BUFFER)
    {
        *isPackaged = true;
        return ERROR_SUCCESS;
    }

    if (result == APPMODEL_ERROR_NO_PACKAGE)
    {
        return ERROR_SUCCESS;
    }

    return result;
}

Cette vérification n’a pas besoin de récupérer le nom complet du package. Si vous avez également besoin de la valeur d’identité, allouez une mémoire tampon de la longueur retournée et appelez GetCurrentPackageFullName à nouveau.

Utiliser la fonction GetCurrentPackageFullName dans le code managé

Utilisez l’appel de plateforme pour appeler GetCurrentPackageFullName à partir de .NET :

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

internal static class PackageIdentity
{
    private const int ErrorInsufficientBuffer = 122;
    private const int AppModelErrorNoPackage = 15700;

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    private static extern int GetCurrentPackageFullName(
        ref int packageFullNameLength,
        IntPtr packageFullName);

    public static bool IsPackagedProcess()
    {
        var length = 0;
        var result = GetCurrentPackageFullName(ref length, IntPtr.Zero);

        return result switch
        {
            ErrorInsufficientBuffer => true,
            AppModelErrorNoPackage => false,
            _ => throw new Win32Exception(result),
        };
    }
}

Ne traitez pas chaque valeur de retour différente de zéro comme signifiant que le processus n’est pas empaqueté. Les valeurs autres que ERROR_INSUFFICIENT_BUFFER et APPMODEL_ERROR_NO_PACKAGE indiquent des erreurs.