如何在Windows 8和10中枚举已安装的StoreApps及其ID

我想得到的是所有已安装的StoreApp应用程序的AppUserModelId,以便我可以将它传递给IApplicationActivationManager->ActivateApplication

Windows 8中,它被存储在registry中,但在Windows 10中已不再存在。

在互联网上有很多关于这个问题,但即使经过几天的search,我找不到一个令人满意的解决scheme。

我到目前为止是以下几点:

  1. 我创build了一个IPackageManager的实例,
  2. 我使用当前用户的SID调用FindPackagesByUserSecurityId()
  3. 我遍历返回的集合
  4. 我得到一个IPackage接口
  5. 从那我得到一个IPackageId接口,
  6. 然后我调用IPackageId->get_FamilyName()

与此我举例来说,在Windows计算机上的Windows 10string“ Microsoft.WindowsCalculator_8wekyb3d8bbwe ”。

当我追加到这个string的“ !App ”我有完整的AppUserModelId启动Windows计算器:“ Microsoft.WindowsCalculator_8wekyb3d8bbwe!App

但并不是所有的应用程序都使用FamilyName后面的“ !App ”。 例如,Spartan使用不以“ !App ”结尾的AppUserModelId“ Microsoft.Windows.Spartan_cw5n1h2txyewy!Microsoft.Spartan.Spartan ”。 当我用“ !App ”replace“ !Microsoft.Spartan.Spartan ”时,它将不会启动 – >“这个应用程序不支持指定的合同”。

所以我的问题是我从哪里得到最后一个缺失的部分?

我在网上find了一个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 

所以缺less的是$Application.Id

如果我能得到一个IAppInfo接口,无论如何,我可以调用IAppInfo->get_Id() ,我会准备好。

但是我不知道如何从C ++的IPackage中获得这个。

难以置信,没有人有想法! 这显示了微软如何使我们的生活艰难。 像使用AppUserModelId枚举已安装的StoreApps这样的通用任务需要一个科研部门。

我终于找到了一个能够在Windows 8和Windows 10上完美运行的解决方案。但是需要很多代码。

看起来,Windows并没有在内存中保存应用程序ID,也没有API来直接确定它们。 我研究了Windows 10 SDK中的所有头文件,并找不到对应该任务的相应接口。

但我发现如何得到它们。 我在问题的六个步骤之后继续:

  1. 调用IPackage->get_InstalledLocation()返回一个IStorageFolder
  2. QueryInterface为IStorageItem
  3. 调用IStorageItem->get_Path()

现在你已经安装了应用程序的路径。 Windows 10使用两个基本文件夹:

  • C:\ Program Files \ WindowsApps
  • C:\ WINDOWS \ SystemApps

和其他几个人一样

  • C:\ WINDOWS \ vpnplugins
  • C:\ WINDOWS \ devicesflow
  • C:\ WINDOWS \ MicracastView
  • C:\ WINDOWS \ PrintDialog类
  • C:\ WINDOWS \ PrintDialog3D
  • C:\ WINDOWS \ WinStore

在返回的文件夹路径中,您将找到一个文件“ 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> 

瞧,他们在那里。 这个软件包有两个应用程序ID:“ microsoft.windowslive.mail ”和“ microsoft.windowslive.calendar ”。

然后你从第6步中取出包的FamilyName后附上一个“!” 并附上这个ID,你就完成了。

这个包可以使用AppUserModelId的IApplicationActivationManager->ActivateApplication()IApplicationActivationManager->ActivateApplication()

  • microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.calendar
  • microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.mail

使用PackageManager API来枚举包和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 } 

有关更多详细信息,请参阅MSDN上的GetPackageApplicationIds(),其中包括工作示例代码https://msdn.microsoft.com/en-us/library/windows/desktop/dn270603(v=vs.85).aspx