使用 powershell 启动 Metro 风格的应用程序

Posted

技术标签:

【中文标题】使用 powershell 启动 Metro 风格的应用程序【英文标题】:Launch Metro style apps using powershell 【发布时间】:2015-10-26 05:26:06 【问题描述】:

我正在尝试为 Windows 10 编写一个将自动启动 Metro 风格应用程序的 powershell 脚本。 Start-Process cmdlet 似乎应该可以工作,但除非我提供到 .exe 的路径,否则我无法让它启动任何东西。

例如,以下输入有效:

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

很遗憾,Metro 风格的应用程序没有可执行文件。我需要使用什么文件来启动它们? 例如,如果我想启动 Windows 应用商店,我该怎么做?

谢谢

【问题讨论】:

【参考方案1】:

现有答案中包含有用的信息,但让我尝试将它们与自动化步骤结合在一起。此答案假定存在特定于应用程序的 URI 协议如果对于给定的应用程序不是这样,请通过 shell: URI 方案调用它,如 accepted answer 所示(将这样的 URI 直接传递给 Start-Process 就足够了;例如,Start-Process shell:AppsFolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App)。请注意,您需要知道应用程序系列名称,其中包括抽象发布者 ID (8wekyb3d8bbwe);Get-AppXPackage 可以帮助发现 - 见下文。

Windows 8+ Metro 风格应用(已过时)又名 UWP 应用程序/AppX 包/Microsoft Store 应用程序最好由 URL 启动 使用特定于应用程序的协议方案

例如,计算器 Windows 10 应用程序定义了两个 URL 协议名称,calculatorms-calculator,这两个名称都可以与结尾的 :Start-Process 一起使用:

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

Microsoft Edge 支持协议 microsoft-edge 等,因此您可以在 Edge 中打开给定的 URL,例如 http://example.org,如下所示:

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

注意在这种情况下,协议名称后面的: 是如何跟一个参数 传递给目标应用程序的。

警告:从 PowerShell (Core) 7.2 开始,许多 AppX 应用程序无法使用 -Wait-PassThru 参数启动 - 请参阅 this GitHub issue。

挑战在于如何通过应用程序名称(包名称)发现给定应用程序的协议名称

以下部分讨论了可以在注册表中找到此信息的位置,并定义了帮助函数 GetAppXUriProtocol,它可以自动执行此发现,允许您通过通配符表达式来定位应用程序,如果确切的包名字未知(这是典型的)。

例如,您可以找到计算器应用程序的协议名称,如下所示:

# 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

也就是说,您可以使用Start-Process calculator:Start-Process ms-calculator: 来启动计算器应用程序。

如果您只需要有关 AppX 包的信息 - 包含协议名称 - 请使用标准 Get-AppXPackage cmdlet;例如:

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

发现 AppX 应用程序的 URL 协议名称:

HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId 注册表位置具有为已安装的 AppX 包命名的子项,它们在 ActivatableClassId\*\CustomProperties 子项的 Name 值中指定它们支持的 URL 协议名称。

以下函数 Get-AppXUriProtocol 通过 Get-AppXPackage cmdlet 和注册表查找检索与给定 AppX 应用程序关联的协议名称。

该功能支持通配符表达式,因此您可以按包名的一部分进行搜索,例如应用程序的通用名;例如Get-AppXUriProtocol *calc*

Get-AppXUriProtocol源代码

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
      
    
  


【讨论】:

【参考方案2】:

如果 appx 已注册 URI 协议方案,您可以使用它启动它。例如,要在 Win8/Win10 中启动 windows 商店,请使用以下代码:

    Start-Process ms-windows-store:

我对启动 Metro 风格应用程序的文档如此之少感到惊讶。

【讨论】:

This command cannot be run due to the error: The system cannot find the file specified. 根据Get-AppxPackage,windows store的名字是“Microsoft.WindowsStore”,请问你是从哪里找到“ms-windows-store”这个名字的? 不是名称,而是注册协议。 (比如在http: )只有部分Appx可以这样打开。 @Luke:ms-windows-store 等协议名称在HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId 的子项中定义在注册表中 - 有关详细信息,请参阅my answer。【参考方案3】:

任何因为 WindowsTerminal 而出现在这里的人,我为我的个人资料编写了这个函数,这样我就可以在不将手从键盘上移开的情况下提升:

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

【讨论】:

很好,但你不需要-FilePath explorer.exe;而是直接使用-FilePath "shell:AppsFolder\$pkgName!App"【参考方案4】:

它声称 Metro 风格的“App Store”应用程序没有传统的可执行文件,所以我开始挖掘一点,它们确实有。从旧的 skool 管理 cmd.exe 尝试:

 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

帮我找到了 Ubuntu 的 exe,"%ProgramW6432%\WindowsApps\CanonicalGroupLimited.Ubuntu18.04onWindows_1804.2019.522.0_x64__79rhkp1fndgsc\ubuntu1804.exe"

【讨论】:

是的,有可执行文件,但您不能总是直接调用它们;例如,从cmd.exe 尝试"C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.1908.0.0_x64__8wekyb3d8bbwe\Calculator.exe",它给出Access is denied。但更大的一点是,即使这样有效,这显然是一种非常繁琐的方法;如果有问题的应用程序定义了 URL 协议,您可以简单地执行 Start-Process calculator: 之类的操作【参考方案5】:

如果您下载 Windows SDK,其中有一个可执行文件,名为: microsoft.windows.softwarelogo.appxlauncher.exe 可用于启动 UWP 应用程序。

格式为: microsoft.windows.softwarelogo.appxlauncher.exe &lt;packageFamilyName&gt;!App

您可以通过查看 kayleeFrye_OnDeck 的回答来获取您应用的 packageFamilyName。

【讨论】:

【参考方案6】:

您可以通过在注册表中导航到此处找到与 Start-Process 一起使用的命令:Computer\HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId

然后展开 ActivatableClassId,然后是应用程序,然后在 CustomProperties 文件夹中查看 Name 的值。

Start-Process 必须使用 PowerShell 运行,因为在 CMD 中无法识别。

我用它来启动 Windows Mail 应用程序。

【讨论】:

【参考方案7】:

我不知道有一种真正通用的方法来做到这一点,但您可能可以通过一些中间检查来弄清楚。

注意:我讨厌使用 PowerShell,所以请原谅从 CMD 调用 PS 东西的怪异

第 1 步:弄清楚你有哪些应用程序。

powershell Get-AppXPackage 将生成所有这些的列表。假设您特别想启动 Desktop App Converter,以便在利用自动化的同时处理一些 Centennial 补丁。因此,我将针对 AppX 列表查询可能匹配的内容,使用 findstr 过滤返回的内容。

第 2 步:确定您是否已经拥有所需的应用

powershell Get-AppXPackage | findstr /i Desktop

虽然这给了我很多结果,但我可以清楚地看到返回的匹配集为:

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

如果我没有得到类似的东西,下一步自然是得到该死的东西 :) 所以下一步,这可能会变得很棘手,而且你的里程可能会有所不同:

第 3 步:找到应用所在的位置,您可以实际调用它: 我为什么要这样做?因为如果我尝试从 AppXPackage 查询返回的路径运行它,我会得到"Access is denied."

where DesktopAppConverter

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

然后您应该能够采用生成的路径并能够从那里运行它。

【讨论】:

很好,但是Get-AppXPackage 直接支持通配符表达式作为包名,所以你可以这样做Get-AppXPackage *Desktop* 查找文件路径实际上并没有那么有用,因为你无法启动一个 AppX 应用程序方式 - 改用 URL 方案。 感谢Get-AppXPackage 的提醒:) 我认为这个答案已经过时了。接受的答案似乎表明知道路径曾经是在命令行启动它们的唯一方法。 URL 方案 IIRC 仅在开发人员通过手动包含而不是自动支持的方式支持它时才有效,但近年来它可能发生了变化。我记得我们需要在清单文件中设置 URL 方案所需的名称,而不是开箱即用地自动工作。 谢谢 - 没有考虑到 URI 协议名称可能不是强制性的/开箱即用的支持。接受的答案实际上并不使用路径,它使用 shell: 协议方案(尽管您不一定需要文件资源管理器,将这样的 URI 直接传递给 Start-Process 即可;例如,Start-Process shell:AppsFolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App) .对于没有自己的 URL 协议的应用程序,这种晦涩的方式真的是调用它们的唯一方法吗?请注意,您需要知道应用程序系列名称,其中包括抽象发布者 ID (8wekyb3d8bbwe)。 我不确定这是否是当今的唯一方式,但它似乎仍然有效。例如,我可以通过直接调用该目录中的可执行文件 ("C:\Users\user name\AppData\Local\Microsoft\WindowsApps\AppleInc.iTunes_nzyj5cx40ttqa\iTunes.exe") 来启动 iTunes 商店应用程序,但这带有一个关于默认权限的巨大警告; IIRC,您甚至需要手动修改管理员的权限才能访问 WindowsApps 目录。我不记得需要更改权限才能将此问题的已接受答案用于适用的应用程序。【参考方案8】:

商店应用程序只能由 shell 启动。试试这个:

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

【讨论】:

另外,您可以使用以下应用程序 ID 启动您自己的 UWP 应用程序:explorer.exe shell:AppsFolder\18b72f48-axxx-xxxx-xxxx-903bd872921a_h65w5j3hw1x76!App 很好,尽管它可能使您更灵活地将shell: URI 直接传递给Start-Process:Start-Process shell:AppsFolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App。鉴于需要知道包系列名称,其中包括抽象发布者 ID (8wekyb3d8bbwe) - GetAppXPackage 可以帮助发现。但是,如果可能的话,通常更容易通过其特定的 URI 协议方案启动 UWP 应用程序;在手头的情况下:Start-Process ms-clock:

以上是关于使用 powershell 启动 Metro 风格的应用程序的主要内容,如果未能解决你的问题,请参考以下文章

一个Metro风格的开源项目 MahApps.Metro

WinRT/Metro 风格应用程序中基于 ATL 的 COM 对象

Windows 8 Metro 风格应用示例

C# Metro 风格中 IsSubclassOf 或 IsAssignableFrom 的任何替代方案

基于Bootstrap的Metro风格模板

全屏 WPF 程序中的 Metro 风格 Appbar