2017-09-01 165 views
2

我一直在尝试从桌面应用程序获取系统上安装的所有UWP应用程序的显示名称(用户友好的应用程序名称)。我试图从与这些应用程序相对应的注册表项获取的资源字符串上使用SHLoadIndirectString()。让我们以Windows计算器为例。SHLoadIndirectString()如何在内部工作?

SHLoadIndirectString()使用

它的资源串可以从HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\‌​Repository\Packages\‌​Microsoft.WindowsCal‌​culator_10.1705.1301‌​.0_x64__8wekyb3d8bbw‌​e\DisplayName注册表项来获得。 我的系统上的资源字符串是@{Microsoft.WindowsCalculator_10.1705.1301.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.WindowsCalculator/Resources/AppStoreName}

要获得显示名称,我会做SHLoadIndirectString(@{Microsoft.WindowsCalculator_10.1705.1301.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.WindowsCalculator/Resources/AppStoreName})

实验观察

  1. (实验1)我用SHLoadIndirectString()为两个不同的用户(U1,U2和)。 U1的语言设置为英语,U2的语言设置为法语(FR-fr)。当从U1运行SHLoadIndirectString()时,它返回Windows Calculator,对于U2我得到Calculatrice Windows。因此,为同一资源字符串返回的值取决于当前用户的语言设置。
  2. (实验2)我在U2安装了UWP应用程序,并没有SHLoadIndirectString()在DiplayName资源字符串。我在U1中出错,但在U2中,它正确地给了我所需的字符串。
  3. (实验3)当我添加到资源文件(resources.pri)的路径,资源字符串,我没有在U1的错误。之前的资源字符串是@{DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar_5.1.12.0_x64__3nf5xjt6s13jt?ms-resource://DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar/Resources/AppName},稍后我将其修改为@{C:\\Program Files\\WindowsApps\\DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar_5.1.12.0_x64__3nf5xjt6s13jt\\resources.pri?ms-resource://DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar/Resources/AppName},然后传递给SHLoadIndirectString()

寻找解决

  1. SHLoadIndirectString()'s documentation表示,其返回值取决于Shell environment or ResourceContext,没有给每个细节很多。
  2. 试图重新创建Windows NT API来运行Windows应用程序的两个项目是ReactOSwine。我查看了他们的源代码,找到了SHLoadIndirectString()的实现,但代码似乎要做的就是在开始时删除@符号后,在资源字符串上执行LoadLibrary()。这没有任何意义,为什么系统中会有这样的DLL,因为每个应用程序的资源字符串都不同?

+0

这是非常庞大而复杂的API。在更具体的问题? – RbMm

回答

3

在Windows XP升级到Windows 7 SHLoadIndirectString只与@filename.dll,resource语法记录在MSDN上使用LoadLibrary。用于文件类型注册的MUIVerb条目也许是野外最常见的用法。通过的WinRT /现代/店应用使用

在Windows 8它被扩展,以支持其他来源,特别.PRI文件(Package Resource Index)。

要了解它是如何工作的,你可以单步它在一个调试器,但这些实施细节是不是你应该依靠,你应该只使用记录的API。

在Windows 8,它使用各种功能MrmCoreR.dll(mrmcorer!Microsoft::Resources::Runtime::CResource*)提取包的名称,然后将其与构建+ KERNEL32!PackageIdFromFullName + KERNEL32!GetPackagePath一个"\resources.pri"路径,然后调用Bcp47Langs!Windows::Internal::CLanguagesListFactory::GetUserLanguages获得首选语言的列表。然后它建立从路径(其转换\%5)的字符串,因此它可以检查资源串HKCU\Software\Classes\Local Settings\MrtCache下缓存。如果不是,它会使用资源管理器读取字符串。 ResourceContext如何工作(语言,DPI比例等)以及它如何从.pri文件找到真正的源文件的确切细节可能超出了本问题的范围,并且本身也是一个更大的主题。