Winapi SHLoadIndirectString()在内部是如何工作的?

Winapi SHLoadIndirectString()在内部是如何工作的?,winapi,wine,react-os,Winapi,Wine,React Os,我一直在尝试从桌面应用程序获取系统上安装的所有UWP应用程序的显示名称(应用程序的用户友好名称)。我正在尝试对从对应于这些应用程序的注册表项获得的资源字符串使用SHLoadIndirectString()。让我们以windows计算器为例 SHLoadIndirectString()用法 它的资源字符串可以从HKEY\U CLASSES\U ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel获得\‌​存储库

我一直在尝试从桌面应用程序获取系统上安装的所有UWP应用程序的显示名称(应用程序的用户友好名称)。我正在尝试对从对应于这些应用程序的注册表项获得的资源字符串使用
SHLoadIndirectString()
。让我们以windows计算器为例

SHLoadIndirectString()用法

它的资源字符串可以从
HKEY\U CLASSES\U ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel获得\‌​存储库\包\‌​Microsoft.WindowsCal‌​Calator_10.1705.1301‌​.0_x64__8wekyb3d8bbw‌​e\DisplayName
注册表项。 我的系统上的资源字符串是
@{Microsoft.WindowsCalculator_10.1705.1301.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.WindowsCalculator/Resources/AppStoreName}

要获取显示名称,我将执行
SHLoadIndirectString(@{Microsoft.windowscaculator_10.1705.1301.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.WindowsCalculator/Resources/AppStoreName})

实验观察

  • (实验1)我为两个不同的用户(U1和U2)使用了
    SHLoadIndirectString()。U1的语言设置为英语,U2的语言设置为法语(FR)。从U1运行SHLoadIndirectString()时,它返回了
    Windows Calculator
    ,而对于U2,我得到了
    Calculatrice Windows
    。因此,为同一资源字符串返回的值取决于当前用户的语言设置
  • (实验2)我在U2中安装了一个UWP应用程序,并对DiplayName中的资源字符串执行了SHLoadIndirectString()。我在U1中得到了错误,但在U2中,它正确地给出了所需的字符串
  • (实验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-PlaymixRecordsShar_5.1.12.0_x64__3nf5xjt6s13jt\\resources.pri?ms-resource://DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar/Resources/AppName}
    在传递到
    SHLoadIndirectString()
    之前
  • 寻找解决方案

  • 表示其返回值取决于
    Shell环境或ResourceContext
    ,但没有给出每个方面的详细信息
  • 尝试重新创建windows NT API以运行windows应用程序的两个项目是和。我查看了它们的源代码以找到
    SHLoadIndirectString()
    的实现,但这些代码似乎只做了一个
    LoadLibrary()
    在资源字符串上,在删除开头的
    @
    符号后。这没有任何意义,为什么系统中会有这样的dll,因为每个应用程序的资源字符串都不同


  • 从Windows XP到Windows 7
    SHLoadIndirectString
    仅使用
    LoadLibrary
    和MSDN上记录的
    @filename.dll、resource
    语法。文件类型注册的
    MUIVerb
    条目可能是最常见的用法

    在Windows 8中,它被扩展以支持其他源,特别是WinRT/Modern/Store应用程序使用的.PRI文件()

    要确切了解它是如何工作的,您可以在调试器中单步执行它,但这些实现细节不是您应该依赖的,您应该只使用文档化的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
    下。如果没有缓存,它将使用资源管理器读取字符串。具体的工作细节(语言、DPI比例等)它如何从.pri文件中找到真正的源代码可能超出了这个问题的范围,这本身就是一个更大的主题。

    这是一个非常庞大而复杂的api。在哪个更具体的问题中?