[英]How to enumerate the installed StoreApps and their ID in Windows 8 and 10
What I want to get is the AppUserModelId of all installed StoreApp applications, so that I can pass it to IApplicationActivationManager->ActivateApplication
. 我要获取的是所有已安装的StoreApp应用程序的AppUserModelId,以便可以将其传递给
IApplicationActivationManager->ActivateApplication
。
In Windows 8 it was stored in the Registry, but in Windows 10 it is not anymore. 在Windows 8中,它存储在注册表中,但是在Windows 10中,它不再存在。
There are a lot of questions about this in internet but even after days of searching I could not find a satisfying solution. 互联网上对此有很多疑问,但是即使经过几天的搜索,我仍然找不到令人满意的解决方案。
What I have so far is the following: 我到目前为止有以下内容:
IPackageManager
, IPackageManager
的实例, FindPackagesByUserSecurityId()
with the SID of the current user, FindPackagesByUserSecurityId()
, IPackage
interface IPackage
界面 IPackageId
interface, IPackageId
,我得到一个IPackageId
接口, IPackageId->get_FamilyName()
IPackageId->get_FamilyName()
With that I have for example on Windows 10 for the Windows Calculator the string " Microsoft.WindowsCalculator_8wekyb3d8bbwe
". 这样,例如,在Windows 10上,Windows计算器的字符串为“
Microsoft.WindowsCalculator_8wekyb3d8bbwe
”。
When I append to this string an " !App
" I have the complete AppUserModelId to start the Windows Calculator: " Microsoft.WindowsCalculator_8wekyb3d8bbwe!App
" 当我在此字符串后附加一个“
!App
”时,我具有完整的AppUserModelId来启动Windows计算器:“ Microsoft.WindowsCalculator_8wekyb3d8bbwe!App
”
But not all applications use an " !App
" behind the FamilyName. 但是,并非所有应用程序都在FamilyName后面使用“
!App
”。 For example Spartan uses the AppUserModelId " Microsoft.Windows.Spartan_cw5n1h2txyewy!Microsoft.Spartan.Spartan
" which does not end with " !App
". 例如,Spartan使用AppUserModelId“
Microsoft.Windows.Spartan_cw5n1h2txyewy!Microsoft.Spartan.Spartan
”而不以“ !App
”结尾。 And when I replace " !Microsoft.Spartan.Spartan
" with " !App
" it will not start -> "This app does not support the contract specified". 当我将“
!Microsoft.Spartan.Spartan
”替换为“ !App
”时,它将无法启动->“此应用程序不支持指定的合同”。
So my question is where do I get the last missing part from? 所以我的问题是,我从哪里得到最后缺少的部分?
I found a PowerShell code in internet ( http://poshcode.org/5702 ) that seems to do something very similar: 我在互联网( http://poshcode.org/5702 )中发现了一个PowerShell代码,该代码似乎执行了非常相似的操作:
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
}
}
}
}
I really don't understand this cryptic PowerShell stuff, but one line seems interesting to me: 我真的不明白PowerShell这个神秘的东西,但是我觉得其中一行很有趣:
foreach($Application in $_.Package.Applications.Application)
This seems to enumerate Applications in a Package. 这似乎枚举包中的应用程序。
A comment in the same PowerShell code says: 在同一PowerShell代码中的注释说:
# The full AppUserModelId is composed of the package name,
the publisher id, and the app id, such as
Microsoft.ZuneMusic_8wekyb3d8bbwe!Microsoft.ZuneMusic
so what is missing is the $Application.Id
. 所以缺少的是
$Application.Id
。
If I could get an IAppInfo
interface anyhow I could call IAppInfo->get_Id()
and I would be ready. 如果我能以任何方式获得
IAppInfo
接口,我都可以调用IAppInfo->get_Id()
并做好准备。
But I don't know how to get this from an IPackage
in C++. 但是我不知道如何从C ++的
IPackage
中获得它。
Incredible that nobody has an idea! 令人难以置信的是,没人知道! This shows how Microsoft makes us life hard.
这说明了微软如何使我们生活艰难。 Such a universal task like enumerating the installed StoreApps with their AppUserModelId requires a cientific research department.
诸如枚举已安装的StoreApps及其AppUserModelId这样的通用任务需要科研部门。
I finally came to a solution that works perfectly on Windows 8 and Windows 10. But a lot of code is required. 我终于找到了一种可以在Windows 8和Windows 10上完美运行的解决方案。但是需要大量代码。
It seems that Windows does not hold the Application ID's in memory and there is no API to determine them directly. Windows似乎没有在内存中保存应用程序ID,并且没有API可以直接确定它们。 I studied all header files in the Windows 10 SDK and could not find a corresponding interface useful for that task.
我研究了Windows 10 SDK中的所有头文件,但找不到适合该任务的相应接口。
But I found out how to get them. 但是我发现了如何获得它们。 I continue after the 6 steps in my question:
在我的问题中的6个步骤之后,我继续:
IPackage->get_InstalledLocation()
which returns an IStorageFolder
. IPackage->get_InstalledLocation()
返回IStorageFolder
。 IStorageItem
IStorageItem
QueryInterface IStorageItem->get_Path()
IStorageItem->get_Path()
Now you have the path were the App is installed. 现在,您具有安装该应用程序的路径。 Windows 10 uses two base folders:
Windows 10使用两个基本文件夹:
and several others like 和其他一些人一样
In the returned folder path you will find a file " AppxManifest.xml
". 在返回的文件夹路径中,您将找到一个文件“
AppxManifest.xml
”。 This file looks like: 该文件如下所示:
<?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>
And voilà, there they are. 瞧,他们在那里。 This package has two application ID's: "
microsoft.windowslive.mail
" and " microsoft.windowslive.calendar
". 该软件包具有两个应用程序ID:“
microsoft.windowslive.mail
”和“ microsoft.windowslive.calendar
”。
Then you take the package's FamilyName from step 6 append an "!" 然后,从第6步中获取程序包的FamilyName,然后附加“!” and append this ID and you are done.
并附加此ID,您就完成了。
This package can be started with IApplicationActivationManager->ActivateApplication()
using one of the AppUserModelId's: 可以使用以下一种AppUserModelId从
IApplicationActivationManager->ActivateApplication()
启动此程序包:
microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.calendar
" microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.calendar
” microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.mail
" microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.mail
” Use PackageManager APIs to enumerate packages and GetPackageApplicationIds to enumerate applications in a package eg pseudo-code 使用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
}
See GetPackageApplicationIds() on MSDN for more details including working sample code https://msdn.microsoft.com/en-us/library/windows/desktop/dn270603(v=vs.85).aspx 有关更多详细信息,请参见MSDN上的GetPackageApplicationIds(),包括有效的示例代码https://msdn.microsoft.com/zh-cn/library/windows/desktop/dn270603(v=vs.85).aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.