Pakketidentiteit en runtimecontext detecteren

Een proces wordt als pakket uitgevoerd wanneer het een pakket-id heeft. Een proces wordt niet-verpakt wanneer het geen pakketidentiteit heeft. Dit onderscheid is van toepassing op processen in plaats van alleen op toepassingen, omdat achtergrondtaken, out-of-process servers en andere processen ook pakketidentiteit kunnen hebben.

Pakketidentiteit kan afkomstig zijn van een pakket met de toepassingsbestanden of van een pakket met externe locatie. Het detecteren van pakketidentiteit geeft daarom niet aan waar de app-bestanden worden opgeslagen of welk verpakkingsmodel de app gebruikt.

Een app kan de runtime-identiteit controleren voordat deze een functie gebruikt waarvoor pakketidentiteit is vereist, een updatemechanisme selecteert of een opslaglocatie kiest.

Een proces controleren in Taakbeheer

U kunt een actief proces inspecteren zonder de app te wijzigen:

  1. Open Taakbeheer en selecteer Details.
  2. Klik met de rechtermuisknop op een kolomkop en selecteer Kolommen selecteren.
  3. Selecteer Pakketnaam, en selecteer OK.

Het veld Pakketnaam is leeg voor een niet-verpakt proces. Voor een verpakt proces bevat het normaal gesproken de gelokaliseerde weergavenaam van het pakket. Weergavenamen zijn niet per se uniek. Als Taakbeheer de gelokaliseerde resource niet kan oplossen, wordt in plaats daarvan mogelijk een ms-resource: verwijzing weergegeven.

GetCurrentPackageFullName gebruiken in systeemeigen code

GetCurrentPackageFullName aanroepen zonder buffer:

  • ERROR_INSUFFICIENT_BUFFER betekent dat het proces pakketidentiteit heeft.
  • APPMODEL_ERROR_NO_PACKAGE betekent dat het proces geen pakketidentiteit heeft.
  • Elke andere waarde is een fout die uw app moet afhandelen.
#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;
}

Deze controle hoeft de volledige naam van het pakket niet op te halen. Als u ook de identiteitswaarde nodig hebt, wijst u een buffer van de geretourneerde lengte toe en roept u GetCurrentPackageFullName opnieuw aan.

De functie GetCurrentPackageFullName gebruiken in beheerde code

Gebruik platformoproep om GetCurrentPackageFullName vanuit .NET aan te roepen:

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

Behandel niet elke niet-nul retourwaarde als een aanwijzing dat het proces niet verpakt is. Andere waarden dan ERROR_INSUFFICIENT_BUFFER en APPMODEL_ERROR_NO_PACKAGE duiden op fouten.