Я хочу получить AppUserModelId всех установленных приложений StoreApp, чтобы я мог передать его IApplicationActivationManager->ActivateApplication
,
В Windows 8 он был сохранен в реестре, но в Windows 10 его больше нет.
В интернете много вопросов по этому поводу, но даже после нескольких дней поиска я не смог найти удовлетворительного решения.
Что я имею до сих пор, так это следующее:
IPackageManager
,FindPackagesByUserSecurityId()
с SID текущего пользователя,IPackage
интерфейсIPackageId
интерфейс,IPackageId->get_FamilyName()
С этим у меня например на Windows 10 для калькулятора Windows строка «Microsoft.WindowsCalculator_8wekyb3d8bbwe
».
Когда я добавляю к этой строке «!App
«У меня есть полный AppUserModelId для запуска калькулятора Windows:»Microsoft.WindowsCalculator_8wekyb3d8bbwe!App
«
Но не все приложения используют «!App
«За фамилией.
Например, Spartan использует AppUserModelId
«Microsoft.Windows.Spartan_cw5n1h2txyewy!Microsoft.Spartan.Spartan
«который не заканчивается»!App
«. И когда я заменю»!Microsoft.Spartan.Spartan
» с «!App
msgstr «это не запустится ->» Это приложение не поддерживает указанный контракт «.
Итак, мой вопрос: откуда мне взять последнюю недостающую часть?
Я нашел код PowerShell в Интернете (http://poshcode.org/5702) кажется, что-то очень похожее:
Get-AppXPackage $PackageName -pv Package |
Get-AppxPackageManifest | % {
foreach($Application in $_.Package.Applications.Application) {
if($Application.Id -like $AppId) {
if($Protocol -and !($Application.Extensions.Extension.Protocol.Name | ? { ($_ + "://") -match (($Protocol -replace '\*','.*') + "(://)?") })) {
continue
}
[PSCustomObject]@{
# Notice the secret magic property:
PSTypeName = "Microsoft.Windows.Appx.Application"AppUserModelId = $Package.PackageFamilyName + "!" + $Application.Id
}
}
}
}
Я действительно не понимаю этого загадочного PowerShell, но мне кажется интересной одна строка:
foreach($Application in $_.Package.Applications.Application)
Кажется, это перечисляет Приложения в пакете.
Комментарий в том же коде PowerShell гласит:
# The full AppUserModelId is composed of the package name,
the publisher id, and the app id, such as
Microsoft.ZuneMusic_8wekyb3d8bbwe!Microsoft.ZuneMusic
так что не хватает это $Application.Id
,
Если бы я мог получить IAppInfo
интерфейс в любом случае я мог бы позвонить IAppInfo->get_Id()
и я был бы готов.
Но я не знаю, как получить это от IPackage
в C ++.
Невероятно, что ни у кого нет идеи!
Это показывает, как Microsoft усложняет нам жизнь.
Такая универсальная задача, как перечисление установленных StoreApps с их AppUserModelId, требует отдела научных исследований.
Я наконец-то пришел к решению, которое отлично работает на Windows 8 и Windows 10. Но требуется много кода.
Похоже, что Windows не хранит идентификаторы приложений в памяти, и нет API для их непосредственного определения. Я изучил все заголовочные файлы в Windows 10 SDK и не смог найти соответствующий интерфейс, полезный для этой задачи.
Но я узнал, как их получить. Я продолжаю после 6 шагов в моем вопросе:
IPackage->get_InstalledLocation()
который возвращает IStorageFolder
,IStorageItem
IStorageItem->get_Path()
Теперь у вас есть путь, где установлено приложение. Windows 10 использует две базовые папки:
и несколько других, как
В возвращенном пути к папке вы найдете файлAppxManifest.xml
».
Этот файл выглядит так:
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns=".....">
......
......
<Applications>
<Application Id="microsoft.windowslive.mail" Executable="HxMail.exe" EntryPoint="Executable">
......
......
</Application>
<Application Id="microsoft.windowslive.calendar" Executable="HxCalendarAppImm.exe" EntryPoint="Executable">
......
......
</Application>
</Applications>
</Package>
И вуаля, вот они. Этот пакет имеет два идентификатора приложения: «microsoft.windowslive.mail
» а также «microsoft.windowslive.calendar
».
Затем вы берете пакет FamilyName из шага 6 и добавляете «!» и добавьте этот идентификатор, и все готово.
Этот пакет может быть запущен с IApplicationActivationManager->ActivateApplication()
используя один из AppUserModelId:
microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.calendar
«microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.mail
«Используйте API PackageManager для перечисления пакетов и GetPackageApplicationIds для перечисления приложений в пакете, например, псевдокод
FOREACH p IN PackageManager.FindPackagesForUserWithPackageTypes(null,
PackageType_Main|PackageType_Optional)
{
PACKAGE_INFO_REFERENCE pir
OpenPackageInfoByFullName(p.Id.FullName, 0, &pir)
UINT32 n=0
GetPackageApplicationIds(pir, &n, null, null)
BYTE* buffer = new BYTE[n]
UINT32 count=0
GetPackageApplicationIds(pir, &n, buffer, &count)
ClosePackageInfo(pir)
PCWSTR * applicationUserModelIds = reinterpret_cast<PCWSTR*>(buffer);
FOR (i=0; i<count; ++i)
{
PCWSTR applicationUserModelId = applicationUserModelIds[i]
}
delete [] buffer
}
Посмотрите GetPackageApplicationIds () на MSDN для получения дополнительной информации, включая рабочий пример кода
https://msdn.microsoft.com/en-us/library/windows/desktop/dn270603(v=vs.85).aspx