{"id":86,"date":"2026-05-12T13:20:48","date_gmt":"2026-05-12T20:20:48","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/insidemsix\/?p=86"},"modified":"2026-05-12T13:20:48","modified_gmt":"2026-05-12T20:20:48","slug":"is-this-a-packaged-process","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/insidemsix\/is-this-a-packaged-process\/","title":{"rendered":"Is This a Packaged Process?"},"content":{"rendered":"<p>Sometimes you need to know whether the current process has package identity. Certain Windows features require it, and behaviors can differ\u2014both technically and culturally.<\/p>\n<p>For example, classic Windows applications often store settings in the registry, whereas packaged applications typically use <a href=\"https:\/\/learn.microsoft.com\/en-us\/uwp\/api\/windows.storage.applicationdata.localsettings\">ApplicationData.LocalSettings<\/a>.<\/p>\n<p>So how can your code determine whether it is running with package identity \u2014 that is, whether it is a <em>packaged process<\/em>?<\/p>\n<h3>Terminology<\/h3>\n<p>Let&#8217;s begin with clear and unambiguous definitions:<\/p>\n<ul>\n<li><strong>Packaged process<\/strong> &#8212; a process that <strong>HAS<\/strong> package identity<\/li>\n<li><strong>Unpackaged process<\/strong> &#8212; a process that <strong>LACKS<\/strong> package identity<\/li>\n<\/ul>\n<p>We deliberately say <em>process<\/em> rather than <em>application<\/em>. 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.<\/p>\n<h3>Possible Outcomes<\/h3>\n<p>When checking for package identity, there are three possible results:<\/p>\n<ol>\n<li>The process <strong>HAS<\/strong> package identity<\/li>\n<li>The process <strong>LACKS<\/strong> package identity<\/li>\n<li>An <strong>error<\/strong> occurred<\/li>\n<\/ol>\n<h2>The Canonical Check (C++)<\/h2>\n<p>The recommended approach uses <a href=\"https:\/\/learn.microsoft.com\/windows\/win32\/api\/appmodel\/nf-appmodel-getcurrentpackagefullname\">GetCurrentPackageFullName<\/a>:<\/p>\n<pre><code class=\"c++\">...\n#include &lt;appmodel.h&gt;\n\ninline bool is_packaged_process()\n{\n    UINT32 n{};\n    const auto rc{ ::GetCurrentPackageFullName(&n, nullptr) };\n    THROW_HR_IF_MSG(HRESULT_FROM_WIN32(rc), (rc != APPMODEL_ERROR_NO_PACKAGE) && (rc != ERROR_INSUFFICIENT_BUFFER), \"GetCurrentPackageFullName rc=%d\", rc);\n    return rc == ERROR_INSUFFICIENT_BUFFER;\n}\n<\/code><\/pre>\n<p>Why this works<\/p>\n<ul>\n<li><code>ERROR_INSUFFICIENT_BUFFER<\/code> indicates the process <strong>has<\/strong> package identity (the call failed only because a buffer was not provided)<\/li>\n<li><code>APPMODEL_ERROR_NO_PACKAGE<\/code> indicates the process <strong>lacks<\/strong> package identity<\/li>\n<li>Any other value signals a genuine error condition<\/li>\n<\/ul>\n<h2>No-Throw Variant (C++)<\/h2>\n<p>If you prefer error codes over exceptions:<\/p>\n<pre><code class=\"c++\">...\n#include &lt;appmodel.h&gt;\n\ninline HRESULT is_packaged_process_nothrow(bool& isPackagedProcess) noexcept\n{\n    isPackagedProcess = false;\n    UINT32 n{};\n    const auto rc{ ::GetCurrentPackageFullName(&n, nullptr) };\n    RETURN_HR_IF_MSG(HRESULT_FROM_WIN32(rc),\n                     (rc != APPMODEL_ERROR_NO_PACKAGE) && (rc != ERROR_INSUFFICIENT_BUFFER),\n                     \"GetCurrentPackageFullName rc=%d\",\n                     rc);\n    isPackagedProcess = (rc == ERROR_INSUFFICIENT_BUFFER);\n    return S_OK;\n}\n<\/code><\/pre>\n<h2>Bonus: C# Equivalent<\/h2>\n<p>For those working in C#, here&#8217;s the equivalent implementation:<\/p>\n<pre><code class=\"csharp\">using System;\nusing System.ComponentModel;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\ninternal static class PackageIdentity\n{\n    private const uint ERROR_INSUFFICIENT_BUFFER = 122;   \/\/ 0x007A\n    private const uint APPMODEL_ERROR_NO_PACKAGE = 15700; \/\/ 0x3D54\n\n    [DllImport(\"kernel32.dll\", CharSet = CharSet.Unicode, SetLastError = true)]\n    private static extern uint GetCurrentPackageFullName(\n        ref int packageFullNameLength,\n        StringBuilder packageFullName);\n\n    public static bool IsPackagedProcess()\n    {\n        int n = 0;\n        uint rc = GetCurrentPackageFullName(ref n, null);\n        if (rc == ERROR_INSUFFICIENT_BUFFER)\n        {\n            return true;\n        }\n        else if (rc == APPMODEL_ERROR_NO_PACKAGE)\n        {\n            return false;\n        }\n        else\n        {\n            throw new Win32Exception((int)rc);\n        }\n    }\n\n    public static uint IsPackagedProcess_nothrow(out bool isPackaged)\n    {\n        int n = 0;\n        uint rc = GetCurrentPackageFullName(ref n, null);\n        isPackaged = (rc == ERROR_INSUFFICIENT_BUFFER);\n        return rc;\n    }\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes you need to know whether the current process has package identity. Certain Windows features require it, and behaviors can differ\u2014both 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 \u2014 [&hellip;]<\/p>\n","protected":false},"author":911,"featured_media":101,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[9,11,2,10],"class_list":["post-86","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-msix","tag-code","tag-identity","tag-msix","tag-terminology"],"acf":[],"blog_post_summary":"<p>Sometimes you need to know whether the current process has package identity. Certain Windows features require it, and behaviors can differ\u2014both 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 \u2014 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/86","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/users\/911"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/comments?post=86"}],"version-history":[{"count":2,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/86\/revisions"}],"predecessor-version":[{"id":102,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/86\/revisions\/102"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/media\/101"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/media?parent=86"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/categories?post=86"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/tags?post=86"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}