May 12th, 2026
0 reactions

Is This a Packaged Process?

Principal Software Engineer

Sometimes you need to know whether the current process has package identity. Certain Windows features require it, and behaviors can differ—both technically and culturally.

For example, classic Windows applications often store settings in the registry, whereas packaged applications typically use ApplicationData.LocalSettings.

So how can your code determine whether it is running with package identity — that is, whether it is a packaged process?

Terminology

Let’s begin with clear and unambiguous definitions:

  • Packaged process — a process that HAS package identity
  • Unpackaged process — a process that LACKS package identity

We deliberately say process rather than application. The distinction matters: applications have processes, but not all processes are applications. For example, WinRT out-of-process (OOP) servers are processes, yet they are not applications in the traditional sense.

Possible Outcomes

When checking for package identity, there are three possible results:

  1. The process HAS package identity
  2. The process LACKS package identity
  3. An error occurred

The Canonical Check (C++)

The recommended approach uses GetCurrentPackageFullName:

...
#include <appmodel.h>

inline bool is_packaged_process()
{
    UINT32 n{};
    const auto rc{ ::GetCurrentPackageFullName(&n, nullptr) };
    THROW_HR_IF_MSG(HRESULT_FROM_WIN32(rc), (rc != APPMODEL_ERROR_NO_PACKAGE) && (rc != ERROR_INSUFFICIENT_BUFFER), "GetCurrentPackageFullName rc=%d", rc);
    return rc == ERROR_INSUFFICIENT_BUFFER;
}

Why this works

  • ERROR_INSUFFICIENT_BUFFER indicates the process has package identity (the call failed only because a buffer was not provided)
  • APPMODEL_ERROR_NO_PACKAGE indicates the process lacks package identity
  • Any other value signals a genuine error condition

No-Throw Variant (C++)

If you prefer error codes over exceptions:

...
#include <appmodel.h>

inline HRESULT is_packaged_process_nothrow(bool& isPackagedProcess) noexcept
{
    isPackagedProcess = false;
    UINT32 n{};
    const auto rc{ ::GetCurrentPackageFullName(&n, nullptr) };
    RETURN_HR_IF_MSG(HRESULT_FROM_WIN32(rc),
                     (rc != APPMODEL_ERROR_NO_PACKAGE) && (rc != ERROR_INSUFFICIENT_BUFFER),
                     "GetCurrentPackageFullName rc=%d",
                     rc);
    isPackagedProcess = (rc == ERROR_INSUFFICIENT_BUFFER);
    return S_OK;
}

Bonus: C# Equivalent

For those working in C#, here’s the equivalent implementation:

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

internal static class PackageIdentity
{
    private const uint ERROR_INSUFFICIENT_BUFFER = 122;   // 0x007A
    private const uint APPMODEL_ERROR_NO_PACKAGE = 15700; // 0x3D54

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

    public static bool IsPackagedProcess()
    {
        int n = 0;
        uint rc = GetCurrentPackageFullName(ref n, null);
        if (rc == ERROR_INSUFFICIENT_BUFFER)
        {
            return true;
        }
        else if (rc == APPMODEL_ERROR_NO_PACKAGE)
        {
            return false;
        }
        else
        {
            throw new Win32Exception((int)rc);
        }
    }

    public static uint IsPackagedProcess_nothrow(out bool isPackaged)
    {
        int n = 0;
        uint rc = GetCurrentPackageFullName(ref n, null);
        isPackaged = (rc == ERROR_INSUFFICIENT_BUFFER);
        return rc;
    }
}

Author

Howard Kapustein
Principal Software Engineer

MSIX Development Engineer/Architect

0 comments