AlvaStamp ships from the Microsoft Store as an MSIX. Pro includes headless stamping from cmd and PowerShell — which is useless if Windows will not let you type the executable name. This post is the packaging change that makes AlvaStamp.exe --stamp … work after a Store install.

Summary

Problem. An unpackaged Win32 app lives in C:\Program Files\… and, if the installer is well behaved, that folder is on PATH. A Store or sideloaded MSIX app does not. The payload is under C:\Program Files\WindowsApps\<identity>_<version>_…, a directory that is ACL-restricted, renamed on every update, and never added to PATH. Typing AlvaStamp in PowerShell therefore fails with “not recognized”, even though the Start menu tile works. Hard-coding the WindowsApps path is worse: the next Store update moves the folder.

Solution. Declare a windows.appExecutionAlias in Package.appxmanifest. On install, Windows drops a zero-byte reparse point named AlvaStamp.exe into %LOCALAPPDATA%\Microsoft\WindowsApps, which is already on the per-user PATH. Any console, script, or CreateProcess that looks up AlvaStamp.exe is redirected to the packaged identity. Arguments (--stamp, --list, -o) pass through unchanged.

That is one XML extension. The rest of this post is why the default Store install is silent on the command line, what the alias actually is on disk, and the extra console work a GUI (Tauri) app still has to do.

Why the Start menu works and PowerShell does not

MSIX is an identity, not a copy of files into Program Files. After a Store install you have:

PieceWhere it livesWho can use it
Package identitySoftmaticGmbHBerlin.AlvaStamp + publisher CNStart, Settings, Get-AppxPackage
PayloadC:\Program Files\WindowsApps\SoftmaticGmbHBerlin.AlvaStamp_<ver>_x64__…The OS, not a random prompt
Start tileRegistered via <uap:VisualElements>Click / Search
Real AlvaStamp.exeInside that versioned folderNot on PATH

The versioned folder is the important part. A Store update is a new folder plus an identity swap. Anything that stored …\AlvaStamp_2.0.2.0_x64__…\AlvaStamp.exe is stale the next morning.

The usual workarounds are all fragile:

  • Construct the path from Get-AppxPackage. Breaks when the architecture suffix or publisher hash is not what you assumed, and still hits ACLs.
  • Start-Process shell:AppsFolder\…. Starts the app; passing a real argv for --stamp is unpleasant.
  • Pin a shortcut. Fine for humans, useless in a scheduled task that should stamp a folder of invoices at 02:00.

None of those is how you want a Pro CLI to be invoked.

What an app execution alias is

Windows 10 1709 (build 16299) added app execution aliases. Developers declare one in the package manifest; the installer materializes it as a file:

%LOCALAPPDATA%\Microsoft\WindowsApps\AlvaStamp.exe

That folder is already on a default user PATH. Open it in Explorer and the file looks empty — size on disk is zero. It is not an empty file. It is a reparse point with tag IO_REPARSE_TAG_APPEXECLINK (0x8000001B). The reparse data holds the package family name and the executable inside the package. CreateProcess / ShellExecute follow the tag; you never touch the WindowsApps payload yourself.

You can inspect one after install:

fsutil reparsepoint query "$env:LOCALAPPDATA\Microsoft\WindowsApps\AlvaStamp.exe"
where.exe AlvaStamp
Get-Command AlvaStamp

where and Get-Command should both resolve to the WindowsApps alias, not to a target\debug leftover and not to C:\Program Files\WindowsApps\….

Users can turn individual aliases off under Settings → Apps → Advanced app settings → App execution aliases. That is the same list that contains python.exe, notepad.exe, and winget.exe. If someone disables AlvaStamp there, the command disappears until they turn it back on. Uninstalling the package removes the reparse point.

The manifest change

Paths are relative to the AlvaStamp app root (apps/alvastamp). The only file that had to change for the alias itself is Package.appxmanifest.

Namespace

windows.appExecutionAlias lives in the uap5 schema (http://schemas.microsoft.com/appx/manifest/uap/windows10/5). Older Microsoft samples use uap3 plus desktop:ExecutionAlias. Both work; the current packaging docs and the uap5:AppExecutionAlias schema are what we followed.

--- a/Package.appxmanifest
+++ b/Package.appxmanifest
@@
   xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
   xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
+  xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
   xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"

AlvaStamp already targets Windows.Desktop MinVersion="10.0.18362.0" (19H1), which is newer than the 1709 floor for aliases, so no OS bump was required.

The extension

The alias is an <Extensions> child of <Application>, next to the .alvastamp file-type association. Executable is the file inside the package; Alias is the name that appears on PATH. They are the same string here on purpose: scripts that already said AlvaStamp.exe keep working.

--- a/Package.appxmanifest
+++ b/Package.appxmanifest
@@
       <uap:VisualElements
         DisplayName="AlvaStamp by AlvaSuite"
         Description="PDF Watermark Stamper"
       </uap:VisualElements>
+      <Extensions>
+        <uap:Extension Category="windows.fileTypeAssociation"
+          EntryPoint="Windows.FullTrustApplication"
+          Executable="AlvaStamp.exe">
+          <uap:FileTypeAssociation Name="alvastamp">
+            <uap:DisplayName>AlvaStamp Profile</uap:DisplayName>
+            <uap:InfoTip>AlvaStamp profile</uap:InfoTip>
+            <uap:Logo>Assets\AppList.png</uap:Logo>
+            <uap:SupportedFileTypes>
+              <uap:FileType ContentType="application/vnd.alvasuite.alvastamp">.alvastamp</uap:FileType>
+            </uap:SupportedFileTypes>
+          </uap:FileTypeAssociation>
+        </uap:Extension>
+        <uap5:Extension Category="windows.appExecutionAlias"
+          EntryPoint="Windows.FullTrustApplication"
+          Executable="AlvaStamp.exe">
+          <uap5:AppExecutionAlias>
+            <uap5:ExecutionAlias Alias="AlvaStamp.exe" />
+          </uap5:AppExecutionAlias>
+        </uap5:Extension>
+      </Extensions>
     </Application>

Rules that mattered while writing this:

  1. Alias must end in .exe. The schema rejects AlvaStamp without the suffix.
  2. One alias per <Application>. The package has a single application id (AlvaStamp), so one name is the whole surface.
  3. Pick a name that will not collide. If two packages register AlvaStamp.exe, Windows keeps the last one registered. AlvaStamp.exe is specific enough that we are not fighting python.exe.
  4. EntryPoint="Windows.FullTrustApplication" matches the rest of the desktop (sparse / full-trust) package. AlvaStamp already declares runFullTrust; the alias does not add a capability.
  5. Executable is package-relative, not a PATH lookup. It is the same AlvaStamp.exe the visual elements already launch.

The file-type association in the same <Extensions> block is a sibling change from the same edit: double-click / “Open with” on a .alvastamp profile should hit the Store identity, not a leftover target\debug\AlvaStamp.exe. It is not required for the CLI; it is required for Explorer to agree with the alias about which AlvaStamp is installed.

After install: what you type

No extra PATH edit. Open a new cmd or PowerShell window (the alias is created at install time; an already-open shell is fine as long as WindowsApps was already on PATH, which it is on a stock profile).

AlvaStamp.exe --help
AlvaStamp.exe -V
AlvaStamp.exe --stamp "C:\jobs\archive.alvastamp" --list "C:\jobs\files.txt" -o "C:\out"

PowerShell’s PATHEXT includes .EXE, so AlvaStamp --help works as well. Scheduled tasks and other processes should use the .exe form.

Headless --stamp remains a Pro feature. Opening a profile without --stamp still launches the UI, including in Community:

AlvaStamp.exe "C:\jobs\archive.alvastamp"

A GUI subsystem app still needs a console

The alias only starts the process with argv. AlvaStamp is a Tauri desktop app. Release builds are linked as a Windows subsystem binary so a double-click from Start does not flash a console:

#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

A windows subsystem process has no stdin/stdout attached to the parent cmd or PowerShell window. Without extra work, AlvaStamp.exe --help would appear to do nothing.

So the alias and the CLI share a second, older piece of Win32: attach to the parent console when we are going to print (apps/alvastamp/src-tauri/src/cli.rs):

pub fn attach_console() {
    #[cfg(windows)]
    unsafe {
        use windows::Win32::System::Console::{AllocConsole, AttachConsole, ATTACH_PARENT_PROCESS};
        if AttachConsole(ATTACH_PARENT_PROCESS).is_err() {
            let _ = AllocConsole();
        }
    }
}

--help and -V call that from cli_prelude() and exit before the WebView starts. Headless --stamp does the same, then writes progress with WriteConsoleW so Unicode paths survive the console code page. If there is no parent console (a scheduled task with “Run whether user is logged on or not”), AllocConsole is a fallback that nobody will see; the useful case is an interactive prompt.

The alias does not replace this. It only makes the exe findable. The subsystem bit is why a Store GUI app can still behave like a CLI once found.

Things that still go wrong

Stale UserChoice for .alvastamp. If you ever “Open with” a debug build, Windows remembers that unpackaged exe. The Store alias then looks like it “doesn’t work” because Explorer is launching target\debug\AlvaStamp.exe (WebView on localhost:1430) while AlvaStamp.exe from a prompt hits the package. Fix: uninstall the debug association (or uninstall/reinstall the Store app) and pick AlvaStamp by AlvaSuite as the default. The file-type association in the manifest is what makes that identity show up in the picker.

WindowsApps missing from user PATH. Rare, but installers that rewrite the user Path can drop %LOCALAPPDATA%\Microsoft\WindowsApps. where AlvaStamp then fails even though the reparse point exists. Put that directory back on the user Path, not the system Path.

Alias toggled off in Settings. Same symptom as a missing Path entry. Turn AlvaStamp back on under App execution aliases.

Working directory. Explorer “Open with” sets CWD to the file’s folder. A packaged Tauri WebView that then fails to resolve tauri.localhost shows “localhost refused to connect.” That is independent of the alias; the app now pins CWD to the exe directory on GUI launch. The alias path does not have that problem because a prompt’s CWD is whatever the script chose, and headless --stamp never starts the WebView.

Takeaway

A Store/MSIX desktop app is not on PATH until you say so in the manifest. uap5 windows.appExecutionAlias is that declaration: Windows plants a reparse point in %LOCALAPPDATA%\Microsoft\WindowsApps, scripts keep saying AlvaStamp.exe, and Store updates stop being a breaking change for the CLI. Pair it with AttachConsole if the binary is a GUI subsystem app, and with a file-type association if Explorer should open the same identity.

Sources

Microsoft Learn:

Stack Overflow:

Stack: MSIX · Package.appxmanifest · uap5 app execution alias · Tauri 2 · AlvaStamp 2.0.3