{"id":412,"date":"2026-11-10T09:00:57","date_gmt":"2026-11-10T17:00:57","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/insidemsix\/?p=412"},"modified":"2026-11-05T22:59:36","modified_gmt":"2026-11-06T06:59:36","slug":"activation-via-appusermodelid","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/insidemsix\/activation-via-appusermodelid\/","title":{"rendered":"Activation via AppUserModelId"},"content":{"rendered":"<p>An application can be directly\n<a href=\"https:\/\/devblogs.microsoft.com\/insidemsix\/activatable-extension-points\/\">activated<\/a> by calling\n<a href=\"https:\/\/learn.microsoft.com\/windows\/win32\/api\/shobjidl_core\/nf-shobjidl_core-iapplicationactivationmanager-activateapplication\">IApplicationActivationManager::ActivateApplication()<\/a>\nwith its <a href=\"https:\/\/devblogs.microsoft.com\/insidemsix\/applications-are-not-packages\/\">Application User Model ID<\/a>,\nalso known as AppUserModelId or AUMID.<\/p>\n<p>For example, let&#8217;s use a package with this <code>AppxManifest.xml<\/code> fragment:<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;Package ...&gt;\n  &lt;Identity Name=\"Contoso.PointOfSale\"\n            Publisher=\"CN=Contoso LLC, O=Contoso LLC, L=Paris, C=France\"\n            Version=\"1.2.3.4\"\n            ProcessorArchitecture=\"x64\" \/&gt;\n  ...\n  &lt;Applications&gt;\n    &lt;Application Id=\"CardReader\" Executable=\"PointOfSale.exe\" ...&gt;\n...\n&lt;\/Package&gt;\n<\/code><\/pre>\n<p>This package&#8217;s full name is <code>Contoso.PointOfSale_1.2.3.4_x64__eh4htm4n7tdre<\/code>.<\/p>\n<p>The <code>eh4htm4n7tdre<\/code> suffix is the publisher ID derived from the package&#8217;s publisher.<\/p>\n<p>Its package family name is therefore <code>Contoso.PointOfSale_eh4htm4n7tdre<\/code>.<\/p>\n<p>The <code>&lt;Application&gt;<\/code>&#8216;s <code>Id<\/code> attribute is the application&#8217;s\n<a href=\"https:\/\/learn.microsoft.com\/uwp\/schemas\/appxpackage\/appxmanifestschema\/element-application\">Package Relative Application Id<\/a>,\nalso known as PRAID.<\/p>\n<p>An AUMID is a combination of the application&#8217;s package family name and PRAID:<\/p>\n<pre><code>AUMID = &lt;PackageFamilyName&gt; \"!\" &lt;PRAID&gt;\n<\/code><\/pre>\n<p>Thus the card reader&#8217;s AUMID is <code>Contoso.PointOfSale_eh4htm4n7tdre!CardReader<\/code>. We can now activate\nthe application via its AUMID.<\/p>\n<h2>Building StartApp.exe<\/h2>\n<p>Let&#8217;s create <code>StartApp.exe<\/code> demonstrating activation via AppUserModelId in C, C++, and C#.<\/p>\n<h2>StartApp.c<\/h2>\n<p>Windows doesn&#8217;t provide a convenient way to activate an application given an AUMID, so let&#8217;s make one.<\/p>\n<p><code>StartApp.exe<\/code> activates an app by AUMID. Here&#8217;s a minimal low-level implementation:<\/p>\n<pre><code class=\"c\">#define COBJMACROS\n#include &lt;windows.h&gt;\n#include &lt;shobjidl.h&gt;\n\nHRESULT Run(PCWSTR appUserModelId, PCWSTR parameters, DWORD* processId)\n{\n    IApplicationActivationManager *aam = NULL;\n    HRESULT hr = S_OK;\n\n    if (appUserModelId == NULL || *appUserModelId == L'\\0' || processId == NULL)\n    {\n        return E_INVALIDARG;\n    }\n\n    hr = CoCreateInstance(&amp;CLSID_ApplicationActivationManager, NULL,\n        CLSCTX_INPROC_SERVER, &amp;IID_IApplicationActivationManager, (void**)&amp;aam);\n    if (FAILED(hr))\n    {\n        return hr;\n    }\n\n    hr = IApplicationActivationManager_ActivateApplication(aam,\n        appUserModelId, parameters != NULL ? parameters : L\"\", AO_NONE, processId);\n\n    IApplicationActivationManager_Release(aam);\n\n    return hr;\n}\n\nint wmain(int argc, wchar_t* argv[])\n{\n    HRESULT hr = S_OK;\n    DWORD processId = 0;\n\n    if (argc &lt; 2)\n    {\n        wprintf(L\"Usage: StartApp.exe &lt;aumid&gt;\\n\");\n        return ERROR_INVALID_PARAMETER;\n    }\n\n    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);\n    if (FAILED(hr))\n    {\n        return hr;\n    }\n\n    hr = Run(argv[1], NULL, &amp;processId);\n    if (SUCCEEDED(hr))\n    {\n        wprintf(L\"StartApp activated %ls: PID %u\\n\", argv[1], processId);\n    }\n    else\n    {\n        fwprintf(stderr, L\"StartApp failed to activate %ls: 0x%08lX\\n\",\n            argv[1], (unsigned long)hr);\n    }\n\n    CoUninitialize();\n\n    return (int)hr;\n}\n<\/code><\/pre>\n<p>Pretty basic but it gets the job done. This creates the <code>ApplicationActivationManager<\/code> (AAM) instance\nand calls its <code>ActivateApplication()<\/code> method with the AUMID, with basic error handling throughout.<\/p>\n<p>But we can do better.<\/p>\n<h2>StartApp.cpp<\/h2>\n<p>Next, let&#8217;s add support for parameters.<\/p>\n<p>We&#8217;ll also switch to Modern C++ and\n<a href=\"https:\/\/github.com\/microsoft\/wil\">Windows Implementation Library<\/a> (WIL) for ease of use and improved error handling.<\/p>\n<pre><code class=\"c++\">#include &lt;windows.h&gt;\n#include &lt;shobjidl.h&gt;\n\n#include &lt;string&gt;\n\n#include &lt;wil\/com.h&gt;\n#include &lt;wil\/resource.h&gt;\n#include &lt;wil\/result.h&gt;\n\nDWORD Run(const std::wstring&amp; appUserModelId, const std::wstring&amp; parameters)\n{\n    THROW_HR_IF(E_INVALIDARG, appUserModelId.empty());\n\n    auto aam{ wil::CoCreateInstance&lt;IApplicationActivationManager&gt;(CLSID_ApplicationActivationManager) };\n\n    DWORD processId{};\n    THROW_IF_FAILED(aam-&gt;ActivateApplication(\n        appUserModelId.c_str(), parameters.c_str(), AO_NONE, &amp;processId));\n\n    return processId;\n}\n\nint wmain(int argc, wchar_t* argv[])\n{\n    if (argc &lt; 2)\n    {\n        std::fwprintf(stderr, L\"Usage: StartApp.exe &lt;aumid&gt; [parameters...]\\n\");\n        return ERROR_INVALID_PARAMETER;\n    }\n\n    const std::wstring appUserModelId{ argv[1] };\n\n    \/\/ Handling backslashes, quotes, spaces and other complexities in argv\n    \/\/ is left as an exercise for the reader :-)\n    std::wstring parameters;\n    for (int index = 2; index &lt; argc; ++index)\n    {\n        if (index &gt; 2)\n        {\n            parameters += L' ';\n        }\n        parameters += argv[index];\n    }\n\n    try\n    {\n        const auto com{ wil::CoInitializeEx(COINIT_APARTMENTTHREADED) };\n\n        const auto processId{ Run(appUserModelId, parameters) };\n        wprintf(L\"StartApp activated %ls with \\\"%ls\\\": PID %u\\n\",\n            appUserModelId.c_str(), parameters.c_str(), processId);\n    }\n    catch (const wil::ResultException&amp; ex)\n    {\n        std::fwprintf(stderr, L\"StartApp failed to activate %ls: 0x%08lX\\n\",\n            appUserModelId.c_str(), static_cast&lt;unsigned long&gt;(ex.GetErrorCode()));\n        return static_cast&lt;int&gt;(ex.GetErrorCode());\n    }\n\n    return 0;\n}\n<\/code><\/pre>\n<p><code>StartApp.exe<\/code> is both simpler and more capable thanks to C++ and WIL. Modern C++ eliminates much of\nthe manual resource management, while WIL provides concise COM helpers and consistent\nexception-based error handling.<\/p>\n<h2>StartApp.cs<\/h2>\n<p>For bonus points, here&#8217; a C# implementation.<\/p>\n<pre><code class=\"csharp\">using System;\nusing System.Runtime.InteropServices;\n\ninternal static class Program\n{\n    private const uint AO_NONE = 0;\n\n    [ComImport]\n    [Guid(\"45BA127D-10A8-46EA-8AB7-56EA9078943C\")]\n    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n    private interface IApplicationActivationManager\n    {\n        int ActivateApplication(\n            [MarshalAs(UnmanagedType.LPWStr)] string appUserModelId,\n            [MarshalAs(UnmanagedType.LPWStr)] string arguments,\n            uint options,\n            out uint processId);\n\n        int ActivateForFile(\n            IntPtr itemArray,\n            [MarshalAs(UnmanagedType.LPWStr)] string verb,\n            out uint processId);\n\n        int ActivateForProtocol(\n            IntPtr itemArray,\n            out uint processId);\n    }\n\n    [ComImport]\n    [Guid(\"2E941141-7F97-4756-BA1D-9DECDE894A3D\")]\n    private sealed class ApplicationActivationManager\n    {\n    }\n\n    private static uint Run(string appUserModelId, string parameters)\n    {\n        ArgumentException.ThrowIfNullOrWhiteSpace(appUserModelId);\n\n        var aam = (IApplicationActivationManager)new ApplicationActivationManager();\n\n        var hr = aam.ActivateApplication(\n            appUserModelId, parameters, AO_NONE, out var processId);\n\n        Marshal.ThrowExceptionForHR(hr);\n\n        return processId;\n    }\n\n    public static int Main(string[] args)\n    {\n        if (args.Length &lt; 1)\n        {\n            Console.Error.WriteLine(\n                \"Usage: StartApp.exe &lt;aumid&gt; [parameters...]\");\n            return 2;\n        }\n\n        var appUserModelId = args[0];\n\n        \/\/ Handling backslashes, quotes, spaces and other complexities in argv\n        \/\/ is left as an exercise for the reader :-)\n        var parameters = string.Join(\" \", args[1..]);\n\n        try\n        {\n            var processId = Run(appUserModelId, parameters);\n\n            Console.WriteLine(\n                $\"StartApp activated {appUserModelId} with \\\"{parameters}\\\": PID {processId}\");\n\n            return 0;\n        }\n        catch (Exception ex)\n        {\n            Console.Error.WriteLine(\n                $\"StartApp failed to activate {appUserModelId}: {ex.HResult:X8}\");\n\n            return ex.HResult;\n        }\n    }\n}\n<\/code><\/pre>\n<h2>Activation via AppUserModelId from the Command Line<\/h2>\n<p>Activation by AUMID is fine, but not always convenient. Some tools only know how to run programs via\na command line. Windows doesn&#8217;t include a utility like <code>StartApp.exe<\/code> to facilitate activation by\nAUMID.<\/p>\n<p>You can programmatically define a shortcut on the StartMenu to launch a packaged app by AUMID but\nFile Explorer&#8217;s right-click context menu&#8217;s <code>New &gt; Shortcut<\/code> won&#8217;t accept an AUMID directly.<\/p>\n<p>Is there another option?<\/p>\n<p>Of course.<\/p>\n<p>We&#8217;ll explore several options in the next blog post&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An application can be directly activated by calling IApplicationActivationManager::ActivateApplication() with its Application User Model ID, also known as AppUserModelId or AUMID. For example, let&#8217;s use a package with this AppxManifest.xml fragment: &lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt; &lt;Package &#8230;&gt; &lt;Identity Name=&#8221;Contoso.PointOfSale&#8221; Publisher=&#8221;CN=Contoso LLC, O=Contoso LLC, L=Paris, C=France&#8221; Version=&#8221;1.2.3.4&#8243; ProcessorArchitecture=&#8221;x64&#8243; \/&gt; &#8230; &lt;Applications&gt; &lt;Application Id=&#8221;CardReader&#8221; Executable=&#8221;PointOfSale.exe&#8221; &#8230;&gt; &#8230; &lt;\/Package&gt; [&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":[28,17,9,2,35],"class_list":["post-412","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-msix","tag-activation","tag-application","tag-code","tag-msix","tag-tools"],"acf":[],"blog_post_summary":"<p>An application can be directly activated by calling IApplicationActivationManager::ActivateApplication() with its Application User Model ID, also known as AppUserModelId or AUMID. For example, let&#8217;s use a package with this AppxManifest.xml fragment: &lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt; &lt;Package &#8230;&gt; &lt;Identity Name=&#8221;Contoso.PointOfSale&#8221; Publisher=&#8221;CN=Contoso LLC, O=Contoso LLC, L=Paris, C=France&#8221; Version=&#8221;1.2.3.4&#8243; ProcessorArchitecture=&#8221;x64&#8243; \/&gt; &#8230; &lt;Applications&gt; &lt;Application Id=&#8221;CardReader&#8221; Executable=&#8221;PointOfSale.exe&#8221; &#8230;&gt; &#8230; &lt;\/Package&gt; [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/412","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=412"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/412\/revisions"}],"predecessor-version":[{"id":413,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/412\/revisions\/413"}],"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=412"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/categories?post=412"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/tags?post=412"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}