Запуск приложений в стиле Metro с использованием powershell
Я пытаюсь написать скрипт powershell для Windows 10, который автоматически запускает приложение в стиле Metro. Кажется, что командлет Start-Process должен работать, но я не могу заставить его что-либо запускать, пока не укажу путь к.exe
Например, работает следующий ввод:
Start-Process 'C:\Program Files\Internet Explorer\iexplore.exe'
К сожалению, приложения в стиле Metro не имеют исполняемого файла. Какой файл мне нужно использовать для их запуска? Если бы я хотел запустить Windows Store, например, как бы я это сделал?
Спасибо
9 ответов
Магазин приложений может быть запущен только оболочкой. Попробуй это:
explorer.exe shell:AppsFolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App
Вы можете найти команду для использования с Start-Process, перейдя сюда в реестре: Computer\HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId
Затем разверните ActivatableClassId, затем приложение, затем в папке CustomProperties посмотрите значение для имени.
Start-Process должен запускаться с PowerShell, поскольку он не распознается в CMD.
Я использовал это, чтобы запустить приложение Почты Windows.
Вы должны предоставить название приложения. Например, чтобы запустить Windows Store в Win8/Win10, используйте следующий код:
Start-Process ms-windows-store:
Я был поражен тем, как мало документации для запуска приложений в стиле metro.
В существующих ответах есть полезная информация, но позвольте мне попытаться собрать все это вместе с автоматическими шагами.
В этом ответе предполагается, что каждый пакет AppX имеет как минимум 1 протокол URI для конкретного приложения. Если это не так для данного приложения, вызовите его черезshell:
Схема URI, как показано в принятом ответе (передача такого URI напрямую вStart-Process
достаточно; например,
Start-Process shell:AppsFolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App
). Обратите внимание, что вам необходимо знать название семейства приложений, которое включает абстрактный идентификатор издателя (8wekyb3d8bbwe
);
Get-AppXPackage
может помочь с открытием - см. ниже.
Приложения в стиле Metro для Windows 8+ (устаревший термин), также известные как приложения UWP / пакеты AppX, лучше всего запускать по URL-адресам с использованием схемы протокола для конкретного приложения:
Например, приложение Calculator Windows 10 определяет два имени протокола URL: calculator
а также ms-calculator
, оба из которых могут использоваться с завершающим :
с Start-Process
:
# Note the trailing ":"
Start-Process calculator: # Or: Start-Process ms-calculator:
Microsoft Edge поддерживает протокол microsoft-edge
, среди прочего, чтобы вы могли открыть заданный URL, скажем http://example.org
в Edge следующим образом:
Start-Process microsoft-edge:http://example.org
Обратите внимание, как в этом случае :
после имени протокола следует аргумент для передачи целевому приложению.
Предостережение: начиная с PowerShell Core 7.0.0-preview.5, вы не можете комбинировать этот стиль вызова с-Wait
а также -PassThru
параметры - см. эту проблему GitHub.
Задача состоит в том, чтобы обнаружить имена протоколов данного приложения в его имя приложения (имя пакета).
В следующем разделе обсуждается, где эту информацию можно найти в реестре, и определяется вспомогательная функция. 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
командлет; например:
PS> Get-AppXPackage *calculator*
Name : Microsoft.WindowsCalculator
Publisher : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US
...
Обнаружение имен протоколов URL-адресов приложения AppX:
В HKEY_CLASSES_ROOT\Extensions\ContractId\Windows.Protocol\PackageId
В расположении реестра есть подразделы, названные для установленных пакетов AppX, которые определяют имена протоколов URL, которые они поддерживают в Name
ценности ActivatableClassId\*\CustomProperties
подключи.
Следующая функция, Get-AppXUriProtocol
, извлекает имена протоколов, связанных с данным приложением AppX, через Get-AppXPackage
командлет и поиск в реестре.
Функция поддерживает выражения с подстановочными знаками, поэтому вы можете выполнять поиск по части имени пакета, например по общему имени приложения; например
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
}
}
}
}
Любой, кто появляется здесь и ищет из-за WindowsTerminal, я написал эту функцию для своего профиля, чтобы я мог поднять, не отрывая рук от клавиатуры:
function term {
$pkgName = (Get-AppxPackage -Name Microsoft.WindowsTerminal).PackageFamilyName
$Proc = @{
FilePath = 'explorer.exe'
ArgumentList = "shell:AppsFolder\$pkgName!App"
Verb = 'RunAs'
}
Start-Process @proc
}
Если вы загружаете Windows SDK, там есть исполняемый файл, который называется:microsoft.windows.softwarelogo.appxlauncher.exe
который может быть использован для запуска приложений UWP.
Формат такой:microsoft.windows.softwarelogo.appxlauncher.exe <packageFamilyName>!App
Вы можете получить packageFamilyName своего приложения, посмотрев на ответ kayleeFrye_OnDeck.
Я не знаю действительно универсального способа сделать это, но вы, вероятно, можете выяснить это с помощью пары промежуточных проверок.
примечание: я ненавижу использовать PowerShell, так что извините за странность вызова PS вещей из CMD
Шаг 1: выясните, какие приложения у вас есть.
powershell Get-AppXPackage
сгенерирует список всех из них. Допустим, вы специально хотите запустить Конвертер настольных приложений, чтобы вы могли обрабатывать некоторые исправления Centennial, используя при этом автоматизацию. Поэтому я буду запрашивать у списка AppXs что-то, что может соответствовать 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
После этого вы сможете выбрать этот путь и запустить его оттуда.
Утверждается, что приложения в стиле Metro "App Store" не имеют традиционных исполняемых файлов, поэтому я начал копать немного, и они есть. Из старого skool Administrative 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
Помог мне найти exe для Ubuntu, "%ProgramW6432%\WindowsApps\CanonicalGroupLimited.Ubuntu18.04onWindows_1804.2019.522.0_x64__79rhkp1fndgsc\ubuntu1804.exe"
У меня была аналогичная проблема — и я придумал приведенный ниже код. Обратите внимание, что приведенный ниже код также предоставляет полную необходимую строку, поскольку не все программы UWP используют суффикс «!App». Некоторые из них являются пользовательскими — этот сценарий возвращает полный пакет. имя и тип — в моем случае я генерирую код для пакетных сценариев в последнем столбце — но этот результат можно легко обновить в соответствии с вашими требованиями:
# 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."
}