我一直在尝试从桌面应用程序获取系统上安装的所有UWP应用程序的显示名称(用户友好的应用程序名称)。我正在尝试对从这些应用程序对应的注册表项中获取的资源字符串使用SHLoadIndirectString()
。让我们以windows计算器为例。
SHLoadIndirectString()用法
它的资源字符串可以从HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\Repository\Packages\Microsoft.WindowsCalculator_10.1705.1301.0_x64__8wekyb3d8bbwe\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})
。
实验观察
SHLoadIndirectString()
用于两个不同的用户(U1和U2)。 U1的语言设为英语,U2的语言设为法语(FR-fr)。当从U1运行SHLoadIndirectString()时,它返回Windows Calculator
,而对于U2,我得到了Calculatrice Windows
。因此,为同一资源字符串返回的值取决于当前用户的语言设置。(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()
。寻找解决方案
Shell environment or ResourceContext
,但没有为每个值提供太多详细信息。尝试重新创建Windows NT API以运行Windows应用程序的两个项目是ReactOS和wine。我查看了他们的源代码以查找SHLoadIndirectString()
的实现,但代码似乎所做的就是在开头删除LoadLibrary()
符号后对资源字符串执行@
。这没有任何意义,为什么系统中会有这样的dll,因为每个应用程序的资源字符串都不同?
答案 0 :(得分:3)
从Windows XP到Windows 7 SHLoadIndirectString
仅使用LoadLibrary
并在MSDN上记录了@filename.dll,resource
语法。文件类型注册的MUIVerb
条目可能是在野外看到的最常见的用法。
在Windows 8中,它被扩展为支持其他来源,特别是WinRT / Modern / Store应用程序使用的.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文件中找到真正来源的确切细节可能超出了这个问题的范围,而且本身就是一个更大的主题。