パッケージ ID とランタイム コンテキストを検出する

プロセスは、パッケージ ID を持つ場合に、パッケージ化されます。 プロセスにはパッケージ ID が存在しない場合、パッケージ化されていないとみなされます。 バックグラウンド タスク、アウトプロセス サーバー、その他のプロセスにもパッケージ ID を持つ可能性があるため、この区別はアプリケーションだけでなくプロセスにも適用されます。

パッケージ ID は、アプリケーション ファイルを含むパッケージから取得することも、 外部の場所を持つパッケージから取得することもできます。 そのため、パッケージの識別情報を特定した場合であっても、アプリケーション ファイルがどこに保存されているか、あるいはそのアプリがどのパッケージング モデルを採用しているかはわかりません。

アプリは、パッケージ ID を必要とする機能を使用する前にランタイム識別情報を確認したり、更新メカニズムを選択したり、ストレージの場所を選択したりする場合があります。

タスク マネージャーでプロセスを確認する

アプリを変更することなく、実行中のプロセスを検査できます。

  1. タスク マネージャーを開き、[詳細] を選択します。
  2. 列見出しを右クリックし、列の選択 を選択します。
  3. [パッケージ名] を選択し、[OK] を選択します。

パッケージ化されていないプロセスの場合、[ パッケージ名 ] フィールドは空白です。 パッケージ化されたプロセスの場合、通常はパッケージのローカライズされた表示名が含まれます。 表示名が一意であるとは限りません。 タスク マネージャーがローカライズされたリソースを解決できない場合、代わりに ms-resource: という参照が表示されることがあります。

ネイティブ コードで GetCurrentPackageFullName を使用する

バッファーなしでGetCurrentPackageFullNameを呼び出す:

  • ERROR_INSUFFICIENT_BUFFER は、プロセスにパッケージ ID があることを意味します。
  • APPMODEL_ERROR_NO_PACKAGE は、プロセスにパッケージ ID がないことを意味します。
  • その他の値は、アプリで処理する必要があるエラーです。
#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;
}

このチェックでは、パッケージの完全な名前を取得する必要はありません。 ID の値も必要な場合は、返された長さのバッファを割り当て、GetCurrentPackageFullName を再度呼び出してください。

マネージド コードで GetCurrentPackageFullName 関数を使用する

プラットフォーム呼び出しを使用して、.NETからGetCurrentPackageFullNameを呼び出します。

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

0 以外の戻り値はすべて、プロセスがパッケージ化されていないという意味として扱わないようにしてください。 ERROR_INSUFFICIENT_BUFFERおよびAPPMODEL_ERROR_NO_PACKAGE以外の値はエラーを表します。