如何从 powershell 打开已安装的 Microsoft Store 应用程序?

How to open installed Microsoft Store apps from powershell?

我正在使用此命令获取已安装的 Microsoft Store 应用列表:

Get-AppxPackage -AllUsers

然后我尝试打开一个应用程序:

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

我收到访问错误:

This command cannot be run due to the error: Access is denied.
# 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()

注意:不幸的是,Start-Process -Wait(和 -PassThru)至少不能与某些 Microsoft Store 应用程序一起使用;该问题已在 GitHub issue #10996.

中报告

使用 URI 协议方案 例如 ms-photos: 是最简单的方法,尽管发现给定 Microsoft Store 的应用程序的协议并非易事 - 请参阅 ,它提供了一个辅助函数,Get-AppXUriProtocol,它建立在标准
的基础上 Get-AppXPackage 命令;例如:

# 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...}

如您所见,Microsoft Photos 应用程序有多个与之关联的协议方案,但简单启动该应用程序的明显候选方案是 ms-photos:,它确实有效。


启动 的 Microsoft Store 应用程序定义了 URI 协议方案:

如果给定的应用程序没有定义 URI 协议方案,您必须 - 有点晦涩 - 通过它的 包家族名称 和通用 [ 启动它=24=] URI 协议方案和虚拟 AppsFolder shell 文件夹,后缀 - 通常但不总是 - 带有 !App;两个值得注意的例外:

  • Spotify 需要 !Spotify(正如您自己发现的那样)。

  • 旧版本的 Microsoft Edge过去需要!MicrosoftEdge(但是请注意,Edge确实有用于启动的 URI 协议,microsoft-edge:)。

  • 正如您自己发现的,后缀就是所谓的应用程序ID,它在应用程序的清单文件中定义,appxmanifest.xml ,位于 $env:Programfiles\WindowsApps 下的特定于应用程序的子文件夹中;请注意,清单可以包含 多个 应用程序 ID,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                                                                                                 
    

公平地假设必须使用 first 条目以交互方式启动应用程序,尽管我不清楚是否有官方规则。

使用 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"

请注意,由于可执行文件随后 间接启动 ,实际目标进程(在本例中为 Microsoft.Photos)在 [=17] 时还不能保证存在=] returns,所以需要做更多的工作,首先等待它存在,然后等待它退出。

在最简单但不完全健壮的情况下,插入一个 Start-Sleep 命令,只要您希望创建目标进程最多需要 [=125] 就可以休眠=](实际时间随系统负载变化):

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

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

完全稳健的方法需要更多的工作。


正在将 参数 传递给 Microsoft Store 应用程序:

  • 使用 一般 "shell:AppsFolder$packageFamilyName!App" 方法 ,您似乎可以像往常一样通过 Start-Process' -ArgumentList 传递参数(-Args) 参数;例如,使用 Microsoft Edge(运行 来自 Windows PowerShell - 如果您有旧版 Edge,请将 !App 替换为 `!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'
    
  • 使用特定于应用程序的 URI 方案方法,参数必须作为 URI 的一部分传递(忽略-ArgumentList):

    • 警告我不清楚如何传递多个参数,一般来说,是否有跨应用程序的 标准化 方法来在 URI 中嵌入参数。

    • 例如,Microsoft Edge 似乎只接受一个参数:要打开的站点的URL。 URL 之后的任何内容似乎都被解释为 URL:

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