2017-09-01 69 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文件找到真正的源文件的確切細節可能超出了本問題的範圍,並且本身也是一個更大的主題。