{"id":268,"date":"2026-08-25T09:00:30","date_gmt":"2026-08-25T16:00:30","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/insidemsix\/?p=268"},"modified":"2026-08-25T16:42:11","modified_gmt":"2026-08-25T23:42:11","slug":"types-of-packaged-applications","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/insidemsix\/types-of-packaged-applications\/","title":{"rendered":"What Kind of Packaged Process Is It?"},"content":{"rendered":"<p>As <a href=\"https:\/\/devblogs.microsoft.com\/insidemsix\/is-this-a-packaged-process\/\">previously discussed<\/a>, we can divide processes into the two broad categories of packaged vs unpackaged, based on if the process HAS or LACKS package identity.<\/p>\n<p>Packaged processes can be divided into three broad categories:<\/p>\n<ul>\n<li>Universal<\/li>\n<li>Centennial\/Desktop Bridge<\/li>\n<li>Win32alacarte<\/li>\n<\/ul>\n<p>All three have package identity, but they make different tradeoffs between compatibility and modern packaged behavior.<\/p>\n<h2>RuntimeBehavior<\/h2>\n<p>Packages specify how an application process is created and runs via multiple properties in <code>AppxManifest.xml<\/code>. The <a href=\"https:\/\/learn.microsoft.com\/uwp\/schemas\/appxpackage\/uapmanifestschema\/element-f-application\">RuntimeBehavior<\/a> attribute clearly expresses this:<\/p>\n<p><code>RuntimeBehavior = &lt;windowsApp | packagedClassicApp | win32App&gt;<\/code><\/p>\n<p><code>RuntimeBehavior=\"windowsApp\"<\/code> is a Universal app. It was first introduced in Windows 8<sup>1<\/sup>. New lingo appeared with it, initially referring to unpackaged vs (Universal) packaged apps as &#8216;Classic&#8217; vs &#8216;Modern&#8217;. The latter evolved through several codenames and formal product names over the years:<\/p>\n<pre>Modern\n\u2794 Tailored\n   \u2794 Immersive\n      \u2794 Metro\n         \u2794 Modern\n            \u2794 Universal Windows App (UWA)\n               \u2794 Universal Windows Platform (UWP) app\n<\/pre>\n<p>This naming history explains why the Settings app uses the package name <code>windows.immersivecontrolpanel<\/code>. It also explains why Windows stores it in <code>%windir%\\ImmersiveControlPanel<\/code>.<\/p>\n<p>Universal apps are built on the Windows Runtime (WinRT) application model, using <a href=\"https:\/\/learn.microsoft.com\/uwp\/api\/windows.applicationmodel.core.coreapplication\">CoreApplication<\/a>, historically use <a href=\"https:\/\/learn.microsoft.com\/uwp\/api\/windows.ui.core.corewindow\">CoreWindow<\/a>, and run in an <a href=\"https:\/\/learn.microsoft.com\/windows\/win32\/secauthz\/appcontainer-isolation\">AppContainer<\/a>.<\/p>\n<p><code>RuntimeBehavior=\"packagedClassicApp\"<\/code> identifies a Centennial app. MSIX introduced it in Windows 10 version 1607 (build 14393, aka RS1). Later, Microsoft released it under the official name <code>Desktop\nBridge<\/code>. These are essentially classic Win32 (unpackaged) applications with a WinMain() or main() entrypoint, use HWNDs, can be console applications and <em>can<\/em> run in an AppContainer but not required (and often don&#8217;t). Although &#8216;Centennial&#8217; was the original codename, it&#8217;s persisted in common use as it rolls off the tongue more easily than the alternatives.<\/p>\n<p>MSIX introduced <code>RuntimeBehavior=\"win32App\"<\/code> in Windows 10 version 2004 (build 19041, aka 20H1). This was originally codenamed &#8216;win32alacarte&#8217; because it aimed to allow packaging behaviors to be selectively enabled for compatibility. Many people still informally refer to this as &#8216;Win32alacarte&#8217; to avoid confusing <code>RuntimeBehavior=\"win32App\"<\/code> with traditional unpackaged Win32 applications.<\/p>\n<p>Win32alacarte is similar to Centennial in mechanism (<code>WinMain()<\/code>\/<code>main()<\/code>, HWND, &#8230;) but with a very different guiding principle.<\/p>\n<h2>Centennial vs Win32alacarte<\/h2>\n<p>The difference between Centennial and Win32alacarte is very simple:<\/p>\n<blockquote>\n<p>Centennial&#8217;s goal is &#8220;Be a good Windows citizen&#8221; vs Win32alacarte&#8217;s focus is &#8220;Compatibility&#8221;.<\/p>\n<\/blockquote>\n<h3>Centennial<\/h3>\n<p>Centennial processes behave differently from classic (unpackaged) Win32 processes to be more secure, reliable, cleanly uninstall and generally be better behaved (and with less effort by the developer).<\/p>\n<p>For example, <a href=\"https:\/\/learn.microsoft.com\/windows\/win32\/dlls\/dynamic-link-library-search-order\">DLL Search Order<\/a> for unpackaged apps encompasses 18 ways to resolve DLLs vs <a href=\"https:\/\/learn.microsoft.com\/windows\/win32\/dlls\/dynamic-link-library-search-order#standard-search-order-for-packaged-apps\">8 for Centennial apps<\/a>.<sup>2<\/sup> By excluding locations such as the current directory and entries from PATH, Centennial applications reduce the risk of accidental or malicious DLL hijacking.<\/p>\n<p>For another example, Centennial&#8217;s I\/O virtualization (aka <a href=\"https:\/\/learn.microsoft.com\/windows\/msix\/desktop\/flexible-virtualization\">Flexible Virtualization<\/a>) is enabled for Centennial apps, vs non-existent for unpackaged apps. This helps applications cleanly uninstall because writes are redirected to package-owned locations instead of being scattered throughout the system.<\/p>\n<p>Centennial makes it easier to write well behaved applications, but these differences can be problematic for some (especially older) applications.<\/p>\n<h3>Win32alacarte<\/h3>\n<p>Win32alacarte focuses on compatibility, even if the result is less well behaved than desired. The primary goal of Win32alacarte is to provide package identity with a high degree of compatibility.<\/p>\n<p>For example, a Win32alacarte app supports all 18 DLL search mechanisms. It also doesn&#8217;t provide I\/O virtualization. This is especially useful for older codebases that can&#8217;t run as Centennial apps, or can&#8217;t be migrated in a timely manner.<\/p>\n<p>The spectrum of unpackaged compatibility to good citizen can be visualized as:<\/p>\n<pre>Compatibility \u25c4\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25ba Good Citizen\n              \u251c\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n      unpackaged  Win32alacarte                             Centennial\n<\/pre>\n<h2>Comparison<\/h2>\n<table>\n<thead>\n<tr>\n<th>Type<\/th>\n<th><code>RuntimeBehavior<\/code><\/th>\n<th>Typical model<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Universal<\/td>\n<td>windowsApp<\/td>\n<td>UWP\/WinRT\/AppContainer<\/td>\n<\/tr>\n<tr>\n<td>Centennial<\/td>\n<td>packagedClassicApp<\/td>\n<td>Packaged Win32 with modern behaviors<\/td>\n<\/tr>\n<tr>\n<td>Win32alacarte<\/td>\n<td>win32App<\/td>\n<td>Packaged Win32 prioritizing compatibility<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<p><sup>1<\/sup> The MSIX packaging platform originated as APPX in Windows 8 and has evolved substantially over time.<\/p>\n<p><sup>2<\/sup>See <a href=\"https:\/\/github.com\/microsoft\/WindowsAppSDK\/blob\/main\/specs\/dynamicdependencies\/DynamicDependencies.md#3152-packaged-processes\">3&#46;1.5.2. Packaged Processes<\/a> for more information.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As previously discussed, we can divide processes into the two broad categories of packaged vs unpackaged, based on if the process HAS or LACKS package identity. Packaged processes can be divided into three broad categories: Universal Centennial\/Desktop Bridge Win32alacarte All three have package identity, but they make different tradeoffs between compatibility and modern packaged behavior. [&hellip;]<\/p>\n","protected":false},"author":911,"featured_media":81,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[28,17,8,2,10],"class_list":["post-268","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-msix","tag-activation","tag-application","tag-architecture","tag-msix","tag-terminology"],"acf":[],"blog_post_summary":"<p>As previously discussed, we can divide processes into the two broad categories of packaged vs unpackaged, based on if the process HAS or LACKS package identity. Packaged processes can be divided into three broad categories: Universal Centennial\/Desktop Bridge Win32alacarte All three have package identity, but they make different tradeoffs between compatibility and modern packaged behavior. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/268","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=268"}],"version-history":[{"count":3,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/268\/revisions"}],"predecessor-version":[{"id":292,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/posts\/268\/revisions\/292"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/media\/81"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/media?parent=268"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/categories?post=268"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/insidemsix\/wp-json\/wp\/v2\/tags?post=268"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}