Erkennen des Paketidentitäts- und Laufzeitkontexts

Ein Prozess wird paketiert, wenn er die Paketidentität aufweist. Ein Prozess wird nicht paketiert, wenn er keine Paketidentität hat. Diese Unterscheidung gilt für Prozesse und nicht nur für Anwendungen, da Hintergrundaufgaben, Out-of-Process-Server und andere Prozesse auch Paketidentitäten aufweisen können.

Die Paketidentität kann aus einem Paket stammen, das die Anwendungsdateien enthält, oder aus einem Paket mit externem Speicherort. Daher sagt Ihnen das Erkennen der Paketidentität nicht, wo die Anwendungsdateien gespeichert sind oder welches Paketmodell die App verwendet.

Eine App überprüft möglicherweise ihre Laufzeitidentität, bevor sie ein Feature verwendet, das paketidentität erfordert, einen Updatemechanismus auswählt oder einen Speicherort auswählt.

Überprüfen eines Prozesses im Task-Manager

Sie können einen laufenden Prozess prüfen, ohne die App zu ändern:

  1. Öffnen Sie den Task-Manager, und wählen Sie "Details" aus.
  2. Klicken Sie mit der rechten Maustaste auf eine Spaltenüberschrift, und wählen Sie dann Spalten auswählen aus.
  3. Wählen Sie Paketname und dann OK aus.

Das Feld Paketname ist für einen nicht paketierten Prozess leer. Bei einem verpackten Prozess enthält es normalerweise den lokalisierten Anzeigenamen des Pakets. Anzeigenamen sind nicht garantiert eindeutig. Wenn der Task-Manager die lokalisierte Ressource nicht ermitteln kann, wird stattdessen ein ms-resource: Verweis angezeigt.

Verwenden Sie "GetCurrentPackageFullName" im nativen Code

Rufen Sie GetCurrentPackageFullName ohne Puffer auf:

  • ERROR_INSUFFICIENT_BUFFER bedeutet, dass der Prozess die Paketidentität aufweist.
  • APPMODEL_ERROR_NO_PACKAGE bedeutet, dass der Prozess keine Paketidentität aufweist.
  • Jeder andere Wert ist ein Fehler, den Ihre App behandeln soll.
#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;
}

Diese Überprüfung muss den vollständigen Paketnamen nicht abrufen. Wenn Sie auch den Identitätswert benötigen, weisen Sie einen Puffer der zurückgegebenen Länge zu und rufen Sie GetCurrentPackageFullName erneut auf.

Verwenden der GetCurrentPackageFullName-Funktion in verwaltetem Code

Verwenden Sie den Plattformaufruf, um GetCurrentPackageFullName von .NET aus aufzurufen:

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),
        };
    }
}

Behandeln Sie nicht jeden Rückgabewert ungleich null als Hinweis darauf, dass der Prozess nicht paketiert ist. Andere Werte als ERROR_INSUFFICIENT_BUFFER und APPMODEL_ERROR_NO_PACKAGE stellen Fehler dar.