I have been trying to get display names (user friendly name of an application) of all UWP applications installed on a system from a desktop application. I am trying to use SHLoadIndirectString()
on the resource string obtained from the registry entry corresponding to those apps. Let us take the case of windows calculator.
SHLoadIndirectString() Usage
It's resource string can be obtained from HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\Repository\Packages\Microsoft.WindowsCalculator_10.1705.1301.0_x64__8wekyb3d8bbwe\DisplayName
registry entry.
The resource string on my system for it is @{Microsoft.WindowsCalculator_10.1705.1301.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.WindowsCalculator/Resources/AppStoreName}
To get the display name I would do SHLoadIndirectString(@{Microsoft.WindowsCalculator_10.1705.1301.0_x64__8wekyb3d8bbwe?ms-resource://Microsoft.WindowsCalculator/Resources/AppStoreName})
.
Experimental observation
SHLoadIndirectString()
for two different users (U1, and U2). U1's language was set to english, U2's language was set to french (FR-fr). When SHLoadIndirectString() was run from U1 it returned Windows Calculator
, and for U2 I got Calculatrice Windows
. Thus the value returned for the same resource string depends on language setting of current user.(resources.pri)
, to resource string, I got no error in U1. The resource string earlier was @{DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar_5.1.12.0_x64__3nf5xjt6s13jt?ms-resource://DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar/Resources/AppName}
, which I later modified to @{C:\\Program Files\\WindowsApps\\DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar_5.1.12.0_x64__3nf5xjt6s13jt\\resources.pri?ms-resource://DJiT.edjing-DJmixerconsolestudio-PlayMixRecordShar/Resources/AppName}
before passing to SHLoadIndirectString()
.Finding solutions
Shell environment or ResourceContext
, without giving much details for each.Two projects which try to re create windows NT API to run windows applications are ReactOS and wine. I looked through their source code to find implementation of SHLoadIndirectString()
, but all that the codes seems to do is to do a LoadLibrary()
on the resource string, after removing the @
symbol at the beginning. This doesn't make any sense, why would there be such a dll in a system, as the resource string for every app is different?
From Windows XP to Windows 7 SHLoadIndirectString
only used LoadLibrary
with the @filename.dll,resource
syntax documented on MSDN. The MUIVerb
entry for file type registrations is perhaps the most common usage seen in the wild.
In Windows 8 it was extended to support other sources, specifically .PRI files (Package Resource Index) used by WinRT/Modern/Store apps.
To find out exactly how it works you can single-step it in a debugger but these implementation details are not something you should depend on, you should only use the documented API.
On Windows 8 it uses various functions in MrmCoreR.dll (mrmcorer!Microsoft::Resources::Runtime::CResource*
) to extract the package name, then it builds a path with KERNEL32!PackageIdFromFullName
+KERNEL32!GetPackagePath
+"\resources.pri"
and then it calls Bcp47Langs!Windows::Internal::CLanguagesListFactory::GetUserLanguages
to get a list of preferred languages. It then builds a string from the path (it converts \
to %5
) so it can check if the resource string is cached under HKCU\Software\Classes\Local Settings\MrtCache
. If not it reads the string with the resource manager. The exact details of how a ResourceContext works (language, DPI scale etc.) and how it finds the true source from the .pri file is probably out of scope for this question and a much larger topic in itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With