How to open installed Microsoft Store apps from powershell?

Issue

I’m getting the list of installed Microsoft Store apps with this command:

Get-AppxPackage -AllUsers

And then I try to open an app:

powershell -Command "Start-Process 'C:\Program Files\WindowsApps\Microsoft.Windows.Photos_2021.21070.22007.0_x64__8wekyb3d8bbwe\Microsoft.Photos.exe' -Verb runAs"

I get an access error:

This command cannot be run due to the error: Access is denied.

Solution

# Use the URI scheme of the Microsoft.Photos application.
# Note: Unfortunately, -Wait does *not* work in this case.
Start-Process ms-photos:

# Wait for the process to exit (from what I can tell there's only ever 1
# Microsoft.Photos process).
# The relevant process name was obtained with: Get-Process *Photos*
(Get-Process Microsoft.Photos).WaitForExit()

Note: That Start-Process -Wait (and -PassThru) cannot be used with at least some Microsoft Store applications is unfortunate; the problem has been reported in GitHub issue #10996.

Using a URI protocol scheme such as ms-photos: is the simplest approach, although discovering a given Microsoft Store’s application’s protocol(s) is non-trivial – see this answer, which provides a helper function, Get-AppXUriProtocol, which builds on the standard
Get-AppXPackage cmdlet; e.g.:

# Note: 
#  * Requires custom function Get-AppXUriProtocol from the linked answer.
#  * Must be run in *Windows PowerShell*, because the AppX module
#    isn't supported in PowerShell (Core), as of v7.1.
PS> Get-AppXUriProtocol *Photos* | Format-List

PackageFullName : Microsoft.Windows.Photos_2021.21070.22007.0_x64__8wekyb3d8bbwe
Protocols       : {ms-wcrv, ms-wpdrmv, ms-photos, microsoft.windows.photos.crop...}

As you can see, the Microsoft Photos application has several protocol schemes associated with it, but the obvious candidate for simply launching the application is ms-photos:, which indeed works.


Launching Microsoft Store applications that do not have a URI protocol scheme defined:

If a given application doesn’t define a URI protocol scheme, you must – somewhat obscurely – launch it via its package family name and the general shell: URI protocol scheme and the virtual AppsFolder shell folder, suffixed – typically, but not always – with !App; two notable exceptions:

  • Spotify requires !Spotify (as you’ve discovered yourself).

  • Older versions of Microsoft Edge used to require !MicrosoftEdge (note, however, that Edge does have a URI protocol for lauching, microsoft-edge:).

  • As you have discovered yourself, the suffix is the so-called application ID, which is defined in an application’s manifest file, appxmanifest.xml, located in the app-specific subfolder underneath $env:Programfiles\WindowsApps; note that a manifest can contain multiple application IDs, as is indeed the case for Microsoft Photos:

    # Run in *Windows PowerShell*.
    # For Microsoft Photos, the following application IDs are reported:
    #   'App', 'SecondaryEntry'
    $appManifestPath = (Get-AppxPackage *Photos*)[-1].InstallLocation + '\appxmanifest.xml'
    (
      Select-Xml '//ns:Application' $appManifestPath `
        -Namespace @{ ns='http://schemas.microsoft.com/appx/manifest/foundation/windows10' }
    ).Node.Id                                                                                                 
    

It is unclear to me when a different suffix required and, if so, how it is determined – it may be the application’s display name without spaces; perhaps the application manifest (appxmanifest.xml in the relevant subfolder of $env:Programfiles\WindowsApps – examining it requires an elevated session) and the registry (the relevant subkey of HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId) provide clues.

To demonstrate the technique using Microsoft Photos:

# Get the package family name (the assumption here is that only *1* package matches).
# Note: While you must run the Get-AppXPackage from *Windows PowerShell*
#       you can use the resulting package name to launch the application
#       from PowerShell (Core) too.
$packageFamilyName = (Get-AppXPackage *Photos*).PackageFamilyName

Start-Process "shell:AppsFolder\$packageFamilyName!App"

Note that since the executable is then launched indirectly, the actual target process (Microsoft.Photos in this case) isn’t guaranteed to exist yet when Start-Process returns, so more work is needed to first wait for it to come into existence, and then wait for it to exit.

In the simplest – but not fully robust – case, insert a Start-Sleep command, to sleep as long as you would expect creation of the target process to take at most (the actual timing varies with system load):

Start-Process "shell:AppsFolder\$packageFamilyName!App"

Start-Sleep -Seconds 5 # Wait for the Microsoft.Photos process to be created.
(Get-Process Microsoft.Photos).WaitForExit()

A fully robust approach would require more work.


Passing arguments to Microsoft Store applications:

  • With the general "shell:AppsFolder\$packageFamilyName!App" approach, you can seemingly pass argument as usual, via Start-Process-ArgumentList (-Args) parameter; e.g., with Microsoft Edge (run from Windows PowerShell – if you have an older Edge version, replace !App with `!MicrosoftEdge:

    # Starts Microsoft Edge and opens the specified URLs.
    Start-Process ('shell:AppsFolder\' + (Get-AppXPackage *Edge*)[-1].PackageFamilyName + '!App') `
      -ArgumentList 'http://example.org https://wikipedia.org'
    
  • With the app-specific URI-scheme approach, argument(s) must be passed as part of the URI (-ArgumentList is ignored):

    • Caveat: It is unclear to me how you can pass multiple arguments and, generally, whether there is a standardized method across applications to embed arguments in the URI.

    • For instance, Microsoft Edge seems to accept only one argument: the URL of a site to open. Anything after that one URL is seemingly interpreted as a part of that one URL:

      # Starts Microsoft Edge an opens the specified URL.
      Start-Process 'microsoft-edge:https://en.wikipedia.org?search=wikipedia'
      

[1] I’ve found at least one exception: Microsoft Edge requires suffix !MicrosoftEdge – I don’t know what determines the required suffix, but !App seems to work in most cases.

Answered By – mklement0

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published