2

我需要能够使用 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 引导加载程序标识符?

4

2 回答 2

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,它不同于“{fa926493-6f1c-4193-a414-58f0b2456d1e}”,后者是指向当前引导管理器的链接。

感谢 Microsoft Scripting Guys 和他们的项目:http ://technet.microsoft.com/en-us/magazine/2008.07.heyscriptingguy.aspx?pr=blog拥有链接到当前引导管理器的 GUID 常量。

于 2012-02-23T00:13:09.167 回答
5

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

于 2012-08-22T18:07:19.893 回答