В моем приложении WPF необходимо указать локализованные имена всех приложений Metro/WinRT, установленных для пользователя. Я создал репозиторий для хранения рабочего образца для кода представлено: https://github.com/luisrigoni/metro-apps-listПолучите локализованные дружественные имена для всех приложений winrt/metro, установленных из приложения WPF.
1) Использование PackageManager.FindPackagesForUser()
метод
var userSecurityId = WindowsIdentity.GetCurrent().User.Value;
var packages = packageManager.FindPackagesForUser(userSecurityId);
foreach (var package in packages)
Debug.WriteLine(package.Id.Name);
}
// output:
// Microsoft.BingFinance
// Microsoft.BingMaps
// Microsoft.BingSports
// Microsoft.BingTravel
// Microsoft.BingWeather
// Microsoft.Bing
// Microsoft.Camera
// microsoft.microsoftskydrive
// microsoft.windowscommunicationsapps
// microsoft.windowsphotos
// Microsoft.XboxLIVEGames
// Microsoft.ZuneMusic
// Microsoft.ZuneVideo
Эти выходы не кажется слишком дружелюбно, чтобы показать пользователю ...
2) Чтение AppxManifest.xml
каждого из этих приложений
var userSecurityId = WindowsIdentity.GetCurrent().User.Value;
var packages = packageManager.FindPackagesForUser(userSecurityId);
foreach (var package in packages)
{
var dir = package.InstalledLocation.Path;
var file = Path.Combine(dir, "AppxManifest.xml");
var obj = SerializationExtensions.DeSerializeObject<Package>(file);
if (obj.Applications != null)
{
foreach (var application in obj.Applications)
{
Debug.WriteLine(application.VisualElements.DisplayName);
}
}
}
// output:
// ms-resource:AppTitle
// ms-resource:AppDisplayName
// ms-resource:BingSports
// ms-resource:AppTitle
// ms-resource:AppTitle
// ms-resource:app_name
// ms-resource:manifestDisplayName
// ms-resource:ShortProductName
// ms-resource:mailAppTitle
// ms-resource:chatAppTitle
// ms-resource:///resources/residTitle
// ms-resource:///strings/peopleAppName
// ms-resource:///photo/residAppName
// ms-resource:34150
// ms-resource:33273
// ms-resource:33270
Определенно не дружит ...
Update 1) Увеличение выше пункта (2 ) с SHLoadIndirectString
несильно (намек на Erik F)
[DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)]
private static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved);
static internal string ExtractStringFromPRIFile(string pathToPRI, string resourceKey)
{
string sWin8ManifestString = string.Format("@{{{0}? {1}}}", pathToPRI, resourceKey);
var outBuff = new StringBuilder(1024);
int result = SHLoadIndirectString(sWin8ManifestString, outBuff, outBuff.Capacity, IntPtr.Zero);
return outBuff.ToString();
}
[...]
foreach (var application in obj.Applications)
{
Uri uri = new Uri(application.VisualElements.DisplayName);
var resourceKey = string.Format("ms-resource://{0}/resources/{1}", package.Id.Name, uri.Segments.Last());
Debug.WriteLine(ExtractStringFromPRIFile("<path/to/pri>", resourceKey));
}
[...]
// output:
// Finance
// Maps
// Sports
// Travel
// Weather
// Bing
// Camera
// SkyDrive
// Mail
// Messaging
// Calendar
// People
// Photos
// Games
// Music
// Video
Гораздо, гораздо лучше. У нас уже есть английские этикетки. Но как извлечь другие языковые ресурсы?
Я ожидаю получить тот же ярлык, который отображается на экране запуска для каждого приложения, что-то вроде «Finanças», «Esportes», «Clima», если мой язык pt-BR; «Финансы», «Спорт», «Погода», если мой язык в США.
[Q] Есть ли другой способ получить имена приложений? Может быть, native/Win32 (DISM API/...)? Можно загрузить файл .pri каждого приложения, чтобы получить локализованное имя?
Как уже говорилось, обновленный работающий образец здесь: https://github.com/luisrigoni/metro-apps-list
Эта функция отлично работала для извлечения ресурсов en-us. Как настроить для получения значений ресурсов других языков? –
Этот тип ссылок всегда будет использовать ваши языки по умолчанию или переопределение основного языка приложения. Это означает, что вам нужно изменить добавление другого языка в передний план списка языков вашего профиля пользователя на панели управления. –
Что делать, если я использую этот метод для приложения, которое установлено для другого пользователя, а у пользователя другой язык, чем у моего пользователя? (оба пользователя в той же системе), является 'SHLoadIndirectString()' гарантированным для работы в таком случае. (Я буду использовать SHLoadIndirectString() в строке ресурса, полученной от другого пользователя) –