Доступ к данным конфигурации загрузки Windows 7 с помощью C#
Мне нужно иметь возможность доступа к идентификатору GUID текущей запущенной установки Windows из хранилища данных конфигурации загрузки с помощью C#. Его можно вернуть из командной строки:
bcdedit /enum {current} /v
У меня проблема в том, что в C#, если я пытаюсь напрямую запустить эту команду (даже если программа работает от имени администратора), мне говорят, что bcdedit не существует. Я использую:
ProcessStartInfo procStartInfo = new ProcessStartInfo("bcdedit.exe", "/enum {current} /v");
Другая вещь, которую я исследовал, - это использование WMI, но единственная ссылка, которую я должен сделать, это http://msdn.microsoft.com/en-us/library/windows/desktop/aa362673(v=vs.85).aspx что не очень полезно.
Лучшее решение было бы, если бы мне не приходилось использовать bcdedit, но вместо этого я мог бы использовать собственные классы WMI. Как мне найти текущий идентификатор загрузчика Windows с помощью C#?
2 ответа
Кажется, есть много проблем с прямым доступом к bcdedit.exe, но я смог выяснить, как использовать WMI в C# для доступа к BcdStore:
ConnectionOptions connectionOptions = new ConnectionOptions();
connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
connectionOptions.EnablePrivileges = true;
// The ManagementScope is used to access the WMI info as Administrator
ManagementScope managementScope = new ManagementScope(@"root\WMI", connectionOptions);
// {9dea862c-5cdd-4e70-acc1-f32b344d4795} is the GUID of the System BcdStore
ManagementObject privateLateBoundObject = new ManagementObject(managementScope, new ManagementPath("root\\WMI:BcdObject.Id=\"{9dea862c-5cdd-4e70-acc1-f32b344d4795}\",StoreFilePath=\"\""), null);
ManagementBaseObject inParams = null;
inParams = privateLateBoundObject.GetMethodParameters("GetElement");
// 0x24000001 is a BCD constant: BcdBootMgrObjectList_DisplayOrder
inParams["Type"] = ((UInt32)0x24000001);
ManagementBaseObject outParams = privateLateBoundObject.InvokeMethod("GetElement", inParams, null);
ManagementBaseObject mboOut = ((ManagementBaseObject)(outParams.Properties["Element"].Value));
string[] osIdList = (string[]) mboOut.GetPropertyValue("Ids");
// Each osGuid is the GUID of one Boot Manager in the BcdStore
foreach (string osGuid in osIdList)
{
ManagementObject currentManObj = new ManagementObject(managementScope, new ManagementPath("root\\WMI:BcdObject.Id=\"" + osGuid + "\",StoreFilePath=\"\""), null);
MessageBox.Show("" + currentManObj.GetPropertyValue("Id"));
}
Это получает GUID каждого менеджера загрузки Windows в BcdStore и показывает их в MessageBox. Следует отметить, что у вас должны быть правильные ConnectionOptions и что эта программа должна запускаться от имени администратора.
Спасибо Россу Джонстону за его проект по адресу: http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=18233 чтобы найти константы BCD, и Tran Dinh Hop за его проект по адресу: http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=19208 котором есть весь код C# для работы с BcdStore (за исключением вышеупомянутых констант).
Обновить:
С помощью:
ManagementObject privateLateBoundObject = new ManagementObject(managementScope, new ManagementPath("root\\WMI:BcdObject.Id=\"{fa926493-6f1c-4193-a414-58f0b2456d1e}\",StoreFilePath=\"\""), null);
получит BcdObject для текущего работающего Windows Boot Manager. Если вы тогда позвоните:
currentManObj.GetPropertyValue("Id")
вы получите GUID текущего, работающего Windows Boot Manager, который отличается от "{fa926493-6f1c-4193-a414-58f0b2456d1e}", который является ссылкой на текущий Boot Manager.
Спасибо Microsoft Scripting Guys и их проекту по адресу: http://technet.microsoft.com/en-us/magazine/2008.07.heyscriptingguy.aspx?pr=blog за постоянную GUID, которая связана с текущим Boot Manager.
Обратите внимание, что в%systemroot%\system32 есть только 64-битный файл bcdedit.exe. Если ваше приложение 32-битное, оно не сможет запустить 64-битный bcdedit, потому что слой WOW64 переназначает каталог system32\ в syswow64. Определенно лучше использовать интерфейс WMI.