使用C#访问Windows 7引导配置数据

时间:2012-02-18 00:33:49

标签: c# windows-7 wmi bcdedit bcdstore

我需要能够使用c#从引导配置数据存储中访问当前运行的Windows安装程序的标识符GUID。它可以从运行命令行返回:

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类。如何使用C#找到当前的Windows Boot Loader标识符?

2 个答案:

答案 0 :(得分:8)

直接访问bcdedit.exe似乎有很多问题,但我能够弄清楚如何在C#中使用WMI来访问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"));
}

这将获取BcdStore中每个Windows启动管理器的GUID,并在MessageBox中显示它们。应该注意,您必须拥有正确的ConnectionOptions,并且该程序必须以管理员身份运行。

感谢Ross Johnston的项目:http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=18233找到了BCD常量,并感谢Tran Dinh Hop的项目:http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=19208,其中包含了与BcdStore一起使用的所有C#代码(除上述常数外)。

<强>更新

使用:

ManagementObject privateLateBoundObject = new ManagementObject(managementScope, new ManagementPath("root\\WMI:BcdObject.Id=\"{fa926493-6f1c-4193-a414-58f0b2456d1e}\",StoreFilePath=\"\""), null);

将获取当前正在运行的Windows启动管理器的BcdObject。如果你然后打电话:

currentManObj.GetPropertyValue("Id")

您将获得当前运行的Windows启动管理器的GUID,该GUID与“{fa926493-6f1c-4193-a414-58f0b2456d1e}”不同,后者是指向当前启动管理器的链接。

感谢Microsoft Scripting Guys及其项目:http://technet.microsoft.com/en-us/magazine/2008.07.heyscriptingguy.aspx?pr=blog,以获得链接到当前启动管理器的GUID常量。

答案 1 :(得分:5)

请注意,%systemroot%\ system32中只有64位bcdedit.exe。如果您的应用程序是32位,它将无法启动64位bcdedit,因为WOW64层将system32 \目录重新映射到syswow64。使用WMI界面绝对是最好的。