Mendeteksi identitas paket dan konteks runtime

Proses dipaketkan ketika memiliki identitas paket. Proses tidak dipaketkan ketika tidak memiliki identitas paket. Perbedaan ini berlaku untuk proses, bukan hanya untuk aplikasi, karena tugas latar belakang, server di luar proses, dan proses lain juga dapat memiliki identitas paket.

Identitas paket dapat berasal dari paket yang berisi file aplikasi atau dari paket dengan lokasi eksternal. Oleh karena itu, mendeteksi identitas paket tidak memberi tahu Anda di mana file aplikasi disimpan atau model paket mana yang digunakan aplikasi.

Aplikasi mungkin memeriksa identitas runtime-nya sebelum menggunakan fitur yang memerlukan identitas paket, memilih mekanisme pembaruan, atau memilih lokasi penyimpanan.

Periksa proses di Pengelola Tugas

Anda dapat memeriksa proses yang sedang berjalan tanpa mengubah aplikasi:

  1. Buka Pengelola Tugas dan pilih Detail.
  2. Klik kanan judul kolom, lalu pilih Pilih kolom.
  3. Pilih Nama paket, lalu pilih OK.

Bidang Nama paket kosong untuk proses yang tidak dikemas. Untuk proses yang dikemas, biasanya berisi nama tampilan paket yang dilokalkan. Nama tampilan tidak dijamin unik. Jika Task Manager tidak dapat menemukan sumber daya terlokalkan, mungkin akan menampilkan referensi ms-resource: sebagai gantinya.

Menggunakan GetCurrentPackageFullName dalam kode asli

Panggil GetCurrentPackageFullName tanpa buffer:

  • ERROR_INSUFFICIENT_BUFFER berarti proses memiliki identitas paket.
  • APPMODEL_ERROR_NO_PACKAGE berarti proses tidak memiliki identitas paket.
  • Nilai lain adalah kesalahan yang harus ditangani aplikasi Anda.
#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;
}

Pemeriksaan ini tidak perlu mengambil nama lengkap paket. Jika Anda juga memerlukan nilai identitas, alokasikan buffer dengan panjang yang dikembalikan dan panggil GetCurrentPackageFullName lagi.

Menggunakan fungsi GetCurrentPackageFullName dalam kode terkelola

Gunakan pemanggilan platform untuk memanggil GetCurrentPackageFullName dari .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),
        };
    }
}

Jangan perlakukan setiap nilai pengembalian bukan nol sebagai tanda bahwa prosesnya tidak dikemas. Nilai selain ERROR_INSUFFICIENT_BUFFER dan APPMODEL_ERROR_NO_PACKAGE mewakili kesalahan.