Flopdong
Flopdong

Reputation: 369

Launch Metro style apps using powershell

I am trying to write a powershell script for windows 10 that will automatically launch a Metro-style app. The Start-Process cmdlet seems like it should work, but I cannot get it to launch anything unless I provide a path to the .exe

For example, the following input works:

    Start-Process 'C:\Program Files\Internet Explorer\iexplore.exe'

Unfortunately, Metro-style apps do not have an executable file. What file do I need to use to launch them? If I wanted to launch Windows Store for example, how would I do that?

Thanks

Upvotes: 9

Views: 16050

Answers (10)

mklement0
mklement0

Reputation: 440347

There's helpful information in the existing answers, but let me try to bring it all together, along with automated steps.
This answer assumes the existence of an application-specific URI protocol. If that is not true for a given application, invoke it via the shell: URI scheme as shown in the accepted answer (passing such a URI directly to Start-Process is sufficient; e.g.,
Start-Process shell:AppsFolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App). Note that you need to know the application family name, which includes the abstract publisher ID (8wekyb3d8bbwe);
Get-AppXPackage can help with the discovery - see below.

Windows 8+ Metro-style apps (obsolete term) a.k.a UWP applications / AppX packages / Microsoft Store applications are best launched by URLs using an application-specific protocol scheme:

For instance, the Calculator Windows 10 application defines two URL protocol names, calculator and ms-calculator, both of which can be used with a trailing : with Start-Process:

# Note the trailing ":"
Start-Process calculator: # Or: Start-Process ms-calculator:

Microsoft Edge supports protocol microsoft-edge, among others, so you can open a given URL, say http://example.org in Edge as follows:

Start-Process microsoft-edge:http://example.org

Note how in this case the : after the protocol name is followed by an argument to pass to the target application.

Caveat: As of PowerShell (Core) 7.2, many AppX applications cannot be launched with the -Wait and -PassThru parameters - see GitHub issue #10996.

The challenge is how to discover a given application's protocol names by its application name (package name).

The following section discusses where this information can be found in the registry, and defines custom helper function GetAppXUriProtocol (source code below), which automates this discovery, allowing you to target applications by wildcard expressions, if the exact package name isn't known (which is typical).

For instance, you can find the protocol names for the Calculator application as follows:

# Find the protocol names supported by the Calculator application,
# by wildcard expression rather than full package name.
PS> Get-AppXUriProtocol *calculator*

PackageFullName                                            Protocols
---------------                                            ---------
Microsoft.WindowsCalculator_10.1908.0.0_x64__8wekyb3d8bbwe {calculator, ms-calculator}

That is, you can use Start-Process calculator: or Start-Process ms-calculator: to start the Calculator application.

If you just want information about an AppX package - which does not include the protocol names - use the standard Get-AppXPackage cmdlet; e.g.:

PS> Get-AppXPackage *calculator*
Name              : Microsoft.WindowsCalculator
Publisher         : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
...

Discovering an AppX application's URL protocol names:

The HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId registry location has subkeys named for installed AppX packages, which specify the URL protocol names they support in the Name values of ActivatableClassId\*\CustomProperties subkeys.

The following function, Get-AppXUriProtocol, retrieves the protocol names associated with a given AppX application via the Get-AppXPackage cmdlet and registry lookups.

The function supports wildcard expressions, so you can search by part of a package name, such as an application's common name; e.g.
Get-AppXUriProtocol *calc*

Get-AppXUriProtocol source code:

function Get-AppXUriProtocol {
<#
.SYNOPSIS
Gets the URI protocol names assocated with AppX packages on Windows 8 and above.

.DESCRIPTION
Given AppX package names or wildcard expressions, retrieves all associated
URI protocol names that can be used to launch these applications.

AppX is the package format for UWP applications typically distributed via
the Microsoft Store.

For instance, the protocol names associated with the Windows 10 Calculator
application are 'calculator' and 'ms-calculator', so you can use
Start-Process calculator: (note the appended ":") to launch it.

.PARAMETER PackageName
One or more package family names, full package names, or wildcard expresssions
matching either. 

.EXAMPLE
Get-AppXUriProtocol *calculator*

Outputs a [pscustomobject] instance such as the following:

PackageFullName                                            Protocols
---------------                                            ---------
Microsoft.WindowsCalculator_10.1908.0.0_x64__8wekyb3d8bbwe {calculator, ms-calculator}

#>
  [CmdletBinding(PositionalBinding = $false)]
  [OutputType([pscustomobject])]
  param (
    [Parameter(Mandatory, Position = 0)]
    [SupportsWildcards()]
    [string[]] $PackageName
  )
    
  begin {
    if ($env:OS -ne 'Windows_NT') { Throw "This command is supported on Windows only." }
  }

  process {
    # !! Even though Get-AppXPackage allegedly accepts -Name values from the pipeline
    # !! that doesn't work in practice.
    $packages = foreach ($name in $PackageName) { Get-AppXPackage -Name $name }
    foreach ($package in $packages) {
      $protocolSchemes = (Get-ChildItem registry::HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId\$($package.PackageFullName)\ActivatableClassId\*\CustomProperties).ForEach('GetValue', 'Name')
      [pscustomobject] @{ 
        PackageFullName = $package.PackageFullName
        Protocols       = $protocolSchemes
      }
    }
  }

}

Upvotes: 5

Erstwhile
Erstwhile

Reputation: 1

As @mklement0 mentioned above:

Caveat: As of PowerShell (Core) 7.2, many AppX applications cannot be launched with the -Wait and -PassThru parameters - see GitHub issue #10996.

To work around that I have been using a work around. I was told I should probably post it here. But I don't have enough reputation for a comment.

Start-Process calculator:
Start-Sleep -Seconds 5
Get-Process CalculatorApp | Wait-Process
Write-Warning "App Closed."

This will start Calculator using Start-Process. Grab the Process ID after it starts. Then wait until the App closes.

Upvotes: 0

cerberus1845
cerberus1845

Reputation: 1

I had a similar issue - and came up with the below code - note that the below code also provides the full line required as not all UWP programs use the '!App' suffix.. some are custom - this script pulls back the full package name and type - in my use case I generate a code for batch scripts in the last column - but this output could easily be updated to meet your requirements:

# Function to get the app ID for a given package name
function Get-AppId {
    param (
        [string]$PackageName
    )

    # Get the app package for the given package name
    $appPackage = Get-AppxPackage | Where-Object { $_.Name -eq $PackageName }

    if ($appPackage) {
        return $appPackage.PackageFamilyName
    } else {
        return $null
    }
}

# Get all installed UWP programs
$installedPackages = Get-AppxPackage | Where-Object { $_.IsFramework -eq $false }

if ($installedPackages.Count -gt 0) {
    Write-Host "List of UWP programs with package name, app ID, and batch command:`n"

    # Generate a custom table with formatted columns
    $table = @()
    foreach ($app in $installedPackages) {
        $appName = $app.Name
        $appId = Get-AppId -PackageName $appName

        if ($appId) {
            $packageNameWithAppId = "$appName.$appId"

            # Get the app IDs from the app's manifest
            try {
                $ids = (Get-AppxPackageManifest $app -ErrorAction Stop).Package.Applications.Application.Id
            } catch {
                Write-Output "No IDs found for $($app.Name)" 
            }

            # Construct batch file command for each app ID
            foreach ($id in $ids) {
                $line = [PSCustomObject]@{
                    Name = $appName
                    "Package Name" = $packageNameWithAppId
                    "App ID" = $id
                    "BatchFileCommand" = "start explorer.exe `shell:AppsFolder\$($appId)!$($id)"
                }
                $table += $line
            }
        }
    }

    # Output the formatted table
    $table | Format-Table -AutoSize 

} else {
    Write-Host "No installed UWP programs found."
}

Upvotes: 0

Flopdong
Flopdong

Reputation: 369

If the appx has registered a URI protocol scheme, you can launch it using that. For example, to launch windows store in Win8/Win10, use the following code:

    Start-Process ms-windows-store:

I was amazed at how little documentation there is for launching metro style apps.

Upvotes: 4

batmanama
batmanama

Reputation: 91

Anyone showing up here looking because of WindowsTerminal, I wrote this function for my profile so I can elevate without moving my hands from the keyboard:

function term {
    $pkgName = (Get-AppxPackage -Name Microsoft.WindowsTerminal).PackageFamilyName
    $Proc = @{
        FilePath = 'explorer.exe'
        ArgumentList = "shell:AppsFolder\$pkgName!App"
        Verb = 'RunAs'
    }
    Start-Process @proc
}

Upvotes: 3

noabody
noabody

Reputation: 329

It's asserted the Metro style "App Store" apps don't have traditional executable files so I started digging a little and they do. From an old skool Administrative cmd.exe try:

 dir "%ProgramW6432%\WindowsApps"
 dir "%ProgramW6432%\WindowsApps\Microsoft.WindowsCalculator_10.1903.21.0_x64__8wekyb3d8bbwe"      Directory of C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.1903.21.0_x64__8wekyb3d8bbwe

 04/30/2019  05:58 PM    <DIR>          .
 04/30/2019  05:58 PM    <DIR>          ..
 04/30/2019  05:58 PM            35,314 AppxBlockMap.xml
 04/30/2019  05:58 PM             3,860 AppxManifest.xml
 04/30/2019  05:58 PM    <DIR>          AppxMetadata
 04/30/2019  05:58 PM            11,296 AppxSignature.p7x
 04/30/2019  05:58 PM    <DIR>          Assets
 04/30/2019  05:58 PM         4,188,672 Calculator.exe
 04/30/2019  05:58 PM            95,744 CalculatorApp.winmd
 04/30/2019  05:58 PM           286,920 resources.pri
 04/30/2019  05:58 PM    <DIR>          WinMetadata

Helped me to find the exe for Ubuntu, "%ProgramW6432%\WindowsApps\CanonicalGroupLimited.Ubuntu18.04onWindows_1804.2019.522.0_x64__79rhkp1fndgsc\ubuntu1804.exe"

Upvotes: 0

MidiGlitch
MidiGlitch

Reputation: 11

If you download the Windows SDK, there is an executable in there called: microsoft.windows.softwarelogo.appxlauncher.exe which can be used to launch UWP apps.

The format is: microsoft.windows.softwarelogo.appxlauncher.exe <packageFamilyName>!App

You can get the packageFamilyName of your app by looking at kayleeFrye_OnDeck's answer.

Upvotes: 1

Robin Wilson
Robin Wilson

Reputation: 390

You can locate the command to use with Start-Process by navigating here in the registry: Computer\HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId

Then expand ActivatableClassId, then the app, then in the CustomProperties folder look at the value for Name.

Start-Process must be run with PowerShell as is not recognised in CMD.

I used this to start the Windows Mail app.

Upvotes: 4

kayleeFrye_onDeck
kayleeFrye_onDeck

Reputation: 6978

I don't know of a truly universal way to do this, but you can probably figure it out with a couple intermediary checks.

note: I hate using PowerShell, so pardon the weirdness of calling PS stuff from CMD

Step 1: Figure out what apps you have.

powershell Get-AppXPackage will generate the list of all of them. Let's say you specifically want to launch the Desktop App Converter so you can handle some Centennial patching while leveraging automation. So I'll query against the list of AppXs for something that might match using findstr to filter what comes back.

Step 2: Figure out if you already have the app you want

powershell Get-AppXPackage | findstr /i Desktop

While that gives me back numerous results, I can clearly see set of matches returned as:

Name              : Microsoft.DesktopAppConverter
PackageFullName   : Microsoft.DesktopAppConverter_2.1.1.0_x64__8wekyb3d8bbwe
InstallLocation   : C:\Program Files\WindowsApps\Microsoft.DesktopAppConverter_2.1.1.0_x64__8wekyb3d8bbwe
PackageFamilyName : Microsoft.DesktopAppConverter_8wekyb3d8bbwe

If I didn't get anythign like this back, the natural next step is to get the darned thing :) So for the next step, this could get tricky, and your mileage may vary:

Step 3: Find the location the app exists where you can actually call it: Why am I doing this? Because if I try to run it from the path returned from the AppXPackage query, I'll get "Access is denied."

where DesktopAppConverter

C:\Users\user name\AppData\Local\Microsoft\WindowsApps\DesktopAppConverter.exe 

You should then be able to take that resulting path and be able to run it from there.

Upvotes: 0

user6438653
user6438653

Reputation:

Store Apps can only be started by the shell. Try this:

explorer.exe shell:AppsFolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App

Upvotes: 13

Related Questions