SHLoadIndirectString() 内部如何工作?

Sah*_*ngh 5 winapi wine react-os

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

\n\n

SHLoadIndirectString() 用法

\n\n

HKEY_CLASSES_ROOT\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\AppModel\\\xe2\x80\x8c\xe2\x80\x8bRepository\\Packages\\\xe2\x80\x8c\xe2\x80\x8bMicrosoft.WindowsCal\xe2\x80\x8c\xe2\x80\x8bculator_10.1705.1301\xe2\x80\x8c\xe2\x80\x8b.0_x64__8wekyb3d8bbw\xe2\x80\x8c\xe2\x80\x8be\\DisplayName它的资源字符串可以从注册表项中获取。\n我的系统上它的资源字符串是@{Microsoft.WindowsCalculator_10.1705.1301.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.WindowsCalculator/Resources/AppStoreName}

\n\n

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

\n\n

实验观察

\n\n
    \n
  1. (实验1)我用于SHLoadIndirectString()两个不同的用户(U1和U2)。U1 的语言设置为英语,U2 的语言设置为法语 (FR-fr)。当从 U1 运行 SHLoadIndirectString() 时,它返回Windows Calculator,对于 U2 我得到Calculatrice Windows。因此,同一资源字符串的返回值取决于当前用户的语言设置。
  2. \n
  3. (实验2)我在U2中安装了一个UWP应用程序,并对DiplayName中的资源字符串执行了SHLoadIndirectString()。我在 U1 中遇到错误,但在 U2 中,它正确地给了我所需的字符串。
  4. \n
  5. (实验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()
  6. \n
\n\n

寻找解决方案

\n\n
    \n
  1. SHLoadIndirectString() 的文档说它的返回值取决于Shell environment or ResourceContext,但没有给出每个值的详细信息。
  2. \n
  3. ReactOSwine是两个尝试重新创建 Windows NT API 来运行 Windows 应用程序的项目。我查看了他们的源代码以找到 的实现SHLoadIndirectString(),但代码似乎所做的只是在删除开头的符号LoadLibrary()后对资源字符串执行 a 操作。@这没有任何意义,为什么系统中会有这样的dll,因为每个应用程序的资源字符串都不同?

    \n\n
  4. \n
\n

And*_*ers 5

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

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

要确切了解它是如何工作的,您可以在调试器中单步执行它,但您不应该依赖这些实现细节,您应该只使用记录的 API。

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