Home » Blog
date 16.Mar.2026

■ Add your desktop program to windows 11 modern context menu


Windows explorer and all shell-integrated file managers had an easy time showing the context (right click) menu. And everyone+dog could easily add their program to this menu — and they did in droves. With a simple registry tweak your program would appear as an option when right clicking on your file type. Arguably the situation became unwieldy, too many commands appearing in this valuable system resource. Too many (and buggy) shell extensions slowed things down, and you had to wait ages to see the menu. That's why microsoft decided to restrict access to the new windows 11 file explorer menu. Only certain commands appear in the modern menu version; sundry menu commands were pushed under Show more options.

IMHO microsoft went too far with their restriction policy. Requiring digital signing to close the door to the masses is one thing, but obfuscating the registration procedure for modern context menu handlers is not good sportsmanship. Especially so for "old school" unpackaged desktop programs — you know the actual programs you use that aren't just for social media messaging.

For quite a while my own programs were "poor relatives" relegated to the classic context menu (e.g. "Scan with i-DeClone"). After a week or so battling with "AI" contradictory suggestions I decided to do it the traditional non-AI way (RTFM) and lo and behold: i-DeClone is now in the modern windows 11 context menu! This post is the abbreviated version of my week-long ordeal.

traditional vs modern shell menu

Step by step packaging procedure


To be accepted in the halls of windows 11 context menu, your legacy win32 desktop application needs: Writing a shell extension is straightforward (albeit overdesigned compared to the old registry approach that didn't need a DLL). The incomprehensible part is simulating a Packaged identity for your DLL as if you had a WinUI (store) application. There is a way to have an empty "sparse" package with just manifest information (no executable files), providing the identity to a traditional Win32 program. This sparse package points to an "external location" where your program is stored (installed normally in Program files, not under WindowsApps). So you have a traditional win32 installation that behaves sufficiently "modern" to be accepted to the higher echelons of digital aristocracy :)

A good starting point is the documentation for external location packaging. The basic steps are:

You can download the important manifests I used for declone and replace the key fields with your own information
Let's see each step in detail.


STEP 1. Build your IExplorerCommand shell extension

There are plenty of samples of this skeleton interface implementation. You can use ATL to write a regular COM inproc server DLL or work your head round the WRL/WinRT samples. There's minimal code to write, focusing on these IExplorerCommand methods:

A legacy shell context menu registration would just be a command line under HKCR\.ext\shell\verb that would launch your program with the selected file as a parameter (%1):
"C:\Program Files\zabkat\i-DeClone zap duplicates\declone64.exe" "%1"
Now the same command is started in Invoke using e.g. ShellExecute. The selected file(s) are passed in a IShellItemArray.
Finding the path to execute is very simple with GetModuleFileName. The DLL is usually installed in the same folder as the EXE file. Note that this is a regular COM object unencumbered by packaged apps limitations and virtualizations.

Although this looks like a regular shell extension, it is not registered as a COM object (it will end up under HKCR\PackagedCom). However I advise you during testing to do a regular REGSVR32-type registration, to make sure it works as a basic explorer command (see the test11.REG file in the downloadable above). If all is well your command will appear in the legacy context menu and launch the program; then you can proceed with the mumbo-jumbo packaging.

I have also signed the DLL without establishing the necessity of the step

It is paramount that your DLL also includes a manifest resource with the following MSIX identity:

add inside <assembly>
<msix xmlns="urn:schemas-microsoft-com:msix.v1"
   publisher="CN=Contoso"
   packageName="ContextMenu11"
   applicationId="ContextMenu11" />
where the publisher and package names are identical to those in the MSIX package (STEP 2 below). I have lost 4-5 days banging my head and following chatGPT ludicrous dead-end suggestions until I hit upon this important ingredient. If this is missing, windows explorer won't load the extension!


STEP 2. Create an empty package with identity

The bread and butter of WinUI applications is a folder structure that contains the executable, manifests and various resources. These are automatically created for you by Developer Studio, but in our case we must create the files manually. Our sparse package is declarative and lacks any real content except:

  • The main MSIX manifest AppxManifest.xml
  • A logo PNG
The recommendation is to put everything under a root folder (sparsePack) as in the little folder tree to the right, where images are put under Assets subfolder.
sparsePack\
├─ AppxManifest.xml
├─ Assets\
│   └─ Square44x44Logo.png

That is all for files, the COM object DLL isn't kept in the package. All the magic is in the MSIX manifest. I recommend you start with the template in the documentation, and add your own information. These manifest files aren't meant for human consumption, so just follow the instructions for the various XML fields. In particular:

For modern explorer menu extensions, you need to insert the following Extensions XML block, which isn't in the official documentation. It contains information about the COM server and integration with the shell context menu:

add inside <Application>
<Extensions>
   <desktop4:Extension Category="windows.fileExplorerContextMenus">
     <desktop4:FileExplorerContextMenus>
       <desktop5:ItemType Type="Directory">
         <desktop5:Verb Id="declone11" Clsid="EF7E6726-B4FB-43E2-8F2E-540FFFD904E4" />
       </desktop5:ItemType>
     </desktop4:FileExplorerContextMenus>
   </desktop4:Extension>
   <com:Extension Category="windows.comServer">
     <com:ComServer>
       <com:SurrogateServer  DisplayName="Context menu verb handler">
         <com:Class Id="EF7E6726-B4FB-43E2-8F2E-540FFFD904E4" Path="w11_menu.dll" ThreadingModel="STA"/>
       </com:SurrogateServer>
     </com:ComServer>
   </com:Extension>
</Extensions>

The important variable fields are highlighted in red:

You can see the entire AppxManifest.xml I used for declone for more details.


STEP 3. Build and sign the MSIX sparse package

Now we must build the package "installer" using MAKEAPPX. This and the signtool below are part of windows 11 SDK. Just open a command processor in the folder that contains the root package folder and execute:

makeappx.exe pack /o /d sparsePack /nv /p YOUR.msix

Make sure the PSDK x64 tool folder path is searchable in CMD.EXE, or use the full path to run makeappx e.g c:\path2\sdk11\x64\makeappx.exe. Likewise for signtool below.
If all goes well, you will have your MSIX package ready. If there are packing errors... may the force be with you! (It works with the present state of packaging in 2026).

Use 7-zip or xplorer² Enter archive command to browse into MSIX package contents

The package won't show in the context menu without a digital signature. Local developer self-sign certificates aren't of any use if you want to deploy to end users, so you need a proper CA-trusted certificate. The command you need to sign the package is:

signtool.exe sign /fd SHA256 /a /n "YOUR PFX NAME" /tr http://timestamp.digicert.com /td SHA256 YOUR.msix

where you must replace your own certificate's subject (CN) and your MSIX package name. A timestamp server ensures that the signature will be valid even after your certificate expiers.

I still have a "soft" PFX certificate but down the road everybody will need FIPS or cloud based code signing pipeline.

If you get some SignTool Error: An unexpected internal error has occurred double check the Publisher="CN=xxx" information in the XML manifest. Use CERTMGR.MSC to browse the local certificates and make sure you copy all the data from the subject.


STEP 4. Install program + MSIX identity

The MSIX identity package must be added in your win32 installer (I use NSIS), and installed with powershell. The explorer command DLL will be installed next to your desktop executable, say in C:\program files\my32tool. The trick that bridges the "legacy" and packaged portions is associating the package with the "legacy" installation path. The powershell command is:

PS> Add-AppxPackage -Path YOUR.msix -ExternalLocation "C:\Program Files\my32tool"

The identity package is placed somewhere under C:\Program Files\WindowsApps and the real files in the regular win32 installation folder. The COM object is registered in a special PackagedCom key — you don't need to regsvr32 it.

The documentation shows how to install the package for all users as well

So your existing installation procedure remains the same, only adding a final step for installing the package (only for windows 11 & x64 systems). You just need to figure out how to call powershell from your installer (for NSIS it's nsExec::ExecToLog). Don't forget to add the regular context menu registry snippet under HKCR\Directory\shell so that your old (COM-free) command appears in the legacy context menu. I can't imagine why some programs completely ignore 3rd party file managers that cannot show the modern context menu — it's so easy to maintain backward compatibility!

Regarding future updates, usually your identity doesn't change even if the actual DLL does, so there's no need to reinstall the package. If you do make changes to the identity manifest, make sure you increase the <Identity Version="1.0.0.x"> number and go back to STEP3. Powershell will recognize and install the update — somehow without restarting windows explorer even! To check the installed version use the package with its defined <Identity Name="xxx">:
PS> Get-AppxPackage xxx

For uninstalling the package, use the full powershell command:
powershell.exe -ExecutionPolicy Bypass -Command "Get-AppxPackage PackageName | Remove-AppxPackage"

Whenever I tried to run this command inside powershell, it failed: "Deployment failed with HRESULT: 0x80073CFA", leaving the package half-uninstalled, the registry in tatters etc. However using the entire command above seems to be working without a reboot.

Leftover issues


In the main, the above windows 11 explorer context menu integration works, modernizing your ageing win32 desktop program. There are some leftover glitches for future improvement:

Post a comment on this topic »


©2002-2026 ZABKAT LTD, all rights reserved | Privacy policy | Sitemap