Про что статья?
- Получение списка установленных компонентов Windows используя Microsoft.Dism - Nuget сборку.
- Альтернативный способ получения через работу с утилитой dism.exe.
Что бы сразу уяснить про какие компоненты идёт речь - необходимо зайти в "Установка удаление программ" нажать на кнопку "Установка компонентов Windows" и увидите окно с настройкой (см. картинку).
Данные о компонентах будем получать через DismApi, а вся информация об API есть на сайте msdn Deployment Image Servicing and Management (DISM) API. Так же, есть приложение dism.exe - консольная утилита, для работы с этим API.
Способ 1. Используем Microsoft.Dism.dll сборку.
Для этого нам понадобится подключить Microsoft.Dism сборку из Nuget.
После чего простейший код для вывода всех компонентов выглядит так:
DismApi.Initialize(DismLogLevel.LogErrors); using (var session = DismApi.OpenOnlineSession()) { foreach (DismFeature feature in DismApi.GetFeatures(session)) { Console.WriteLine($"[Feature Name] {feature.FeatureName}"); Console.WriteLine($"[State] {feature.State}"); Console.WriteLine(); } } DismApi.Shutdown();
Данный пример можно проверить скачав его по ссылке в верху страницы. Либо отрыв на Bitbacket: DismWrapperExample.cs
Внимание! Данный способ работает, если есть гарантия, что битность вашего приложения будет ВСЕГДА совпадать с битность операционной системы (Если ваше приложение AnyCPU тогда у вас проблем быть не может). В противном случае следует изучить способ 2.
Способ 2. Парсинг вывода dism.exe.
Теперь представим ситуацию:
- Ваш процесс становится 32 битный (собран под х86 архитектура).
- Операционная система Windows имеет 64 битную разрядность.
В результате чего используя способ 1 мы получим исключение
An unhandled exception of type 'Microsoft.Dism.DismException' occurred in Microsoft.Dism.dll Additional information: An attempt was made to load a program with an incorrect format.
Иными словами мы получили BadImageFormatException исключение, говорящее о невозможности загрузить сборку. Чаще всего возникает, когда пытаются использовать "битую" сборку, либо из под 32 битного процесса пытаются загрузиться сборку скомпилированную под 64 бита. В данном случае подгружается неверная сборка:
В 32 битный процесс подгружается сборка из SysWOW64 (где сборки 64 битные), что приводит к этому эффекту. При этом если сделать процесс 64 битным, тогда под-грузится сборки 32 битные. А как известно 64 битный процесс корректно работает как с 64 битными сборками так и с 32 битными.
Поэтому, что бы решить проблему сборки, можно использовать альтернативный способ получения информации, через парсинг результата вывода утилиты dism.exe.
Утилита умеет выводить в английском языке названия, вне зависимости от языка системы, тем самым можно сделать универсальный распарсиватель и отказаться от использования Microsoft.Dism. Пример вывода:
Исходный код примера на C# можно увидеть по ссылке: Dism32under64CmdExample.cs
Внимание! Если вы скачали мой пример, тогда для демонстрации 2го способа необходима поменять конфигурацию на x86.
Запуск 64 битной командной строки из под 32 битного процесса.
В коде файла Dism32under64CmdExample.cs, есть нюанс работы. Когда мы пытаемся принудительно запустить cmd64.exe вместо cmd.exe, находясь в 32 битном процессе, операционная система сама принудительно будет выбирать cmd в зависимости от битности текущего процесса, а значит выберет 32 битную файл. Для этого можно использовать трюк с mklink для создания символической ссылки на файл, после чего операционная система будет обязана использовать именно тот файл, на который указывает ссылка.
Комментариев нет:
Отправить комментарий