如何从 powershell 打开已安装的 Microsoft Store 应用程序? [英] How to open installed Microsoft Store apps from powershell?

查看:80
本文介绍了如何从 powershell 打开已安装的 Microsoft Store 应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下命令获取已安装的 Microsoft Store 应用程序列表:

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"

我收到访问错误:

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 问题 #10996 中报告.

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.

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

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

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

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.

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

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

如果给定的应用程序没有定义 URI 协议方案,您必须 - 有点模糊 - 通过其包系列名称和一般的 shell: URI 协议方案和虚拟 AppsFolder 外壳文件夹,后缀 - 通常但不总是 - 带有 !App;两个值得注意的例外:

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 需要 !Spotify(正如您自己发现的那样).

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

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

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

正如您自己发现的那样,后缀是所谓的应用程序 ID,它在应用程序的清单文件 appxmanifest.xml 中定义,位于在 $env:Programfiles\WindowsApps 下的特定于应用程序的子文件夹中;请注意,清单可以包含多个应用程序 ID,Microsoft 照片确实如此:

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                                                                                                 

我不清楚什么时候需要不同的后缀,如果需要,它是如何确定的——它可能是应用程序的显示名称,没有空格;也许应用程序清单($env:Programfiles\WindowsApps 的相关子文件夹中的appxmanifest.xml - 检查它需要提升 会话)和注册表(HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId 的相关子项)提供线索.

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.

要演示使用 Microsoft 照片的技术:

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"

请注意,由于可执行文件随后被间接启动,因此当 Start-Process 返回,所以需要做更多的工作,先等待它存在,然后等待它退出.

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.

在最简单但不是完全健壮的情况下,插入一个 Start-Sleep 命令,只要您期望目标进程的创建时间最多就可以休眠(实际时间因系统负载而异):

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.

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

Passing arguments to Microsoft Store applications:

  • 使用一般"shell:AppsFolder\$packageFamilyName!App"方法,您似乎可以像往常一样通过Start-Process' -ArgumentList (-Args) 参数;例如,使用 Microsoft Edge(从 Windows PowerShell 运行 - 如果您使用的是旧版 Edge,请将 !App 替换为 `!MicrosoftEdge:

  • 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'

  • 使用特定于应用程序的 URI 方案方法,参数必须作为 URI 的一部分(-ArgumentList被忽略):

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

    • 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.

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

    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] 我发现至少一个例外:Microsoft Edge 需要后缀 !MicrosoftEdge - 我不知道是什么决定了所需的后缀,但是 !App 似乎在大多数情况下都有效.

    [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.

    这篇关于如何从 powershell 打开已安装的 Microsoft Store 应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆