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:
- The process HAS package identity
- The process LACKS package identity
- 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_BUFFERindicates the process has package identity (the call failed only because a buffer was not provided)APPMODEL_ERROR_NO_PACKAGEindicates 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;
}
}
0 comments
Be the first to start the discussion.