我正在尝试使用bcdedit命令“bcdedit / enum ALL”获取与使用wmi和C#相同的信息。我知道如何获取bootmgr条目(请参阅代码)但我无法获取所有条目,尤其是设备选项是我正在寻找的信息。有没有人知道如何实现这一目标?
这是我用来获取标准和传统os启动条目的代码。
public class BCDWMI
{
public static readonly UInt32 BCDE_STANDARD_OS_ENTRY = 0x10200003;
public static readonly UInt32 BCDE_LEGACY_OS_ENTRY = 0x10300006;
public static readonly UInt32 BcdLibraryElementTypeString_Description = 0x12000004;
public static Dictionary<string, string> EnumerateObjectsByType(uint bcdType, string storePath)
{
Dictionary<string, string> dictEntries = null;
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = ImpersonationLevel.Impersonate;
options.EnablePrivileges = true;
ManagementScope MgmtScope = new ManagementScope("root\\WMI", options);
ManagementPath MgmtPath = new ManagementPath("root\\WMI:BcdStore.FilePath='" + storePath + "'");
ManagementObject bcdStore = new System.Management.ManagementObject(MgmtScope, MgmtPath, null);
ManagementBaseObject[] mboArray;
bool success = EnumerateObjects(bcdStore, bcdType, out mboArray);
if (success)
{
dictEntries = new Dictionary<string, string>();
foreach (ManagementBaseObject mbo in mboArray)
{
ManagementPath BcdObjectPath = new ManagementPath("root\\WMI:BcdObject.Id=\"" + mbo.GetPropertyValue("Id") + "\",StoreFilePath='" + storePath + "'");
ManagementObject BcdObject = new ManagementObject(MgmtScope, BcdObjectPath, null);
ManagementBaseObject Element;
String Description = String.Empty;
try
{
bool getDescripStatus = GetElement(BcdObject, BcdLibraryElementTypeString_Description, out Element);
if (getDescripStatus)
Description = Element.GetPropertyValue("String").ToString();
}
catch (Exception)
{
}
dictEntries.Add((string)mbo.GetPropertyValue("Id"), String.Format("Type: {0:X8} {1}", mbo.GetPropertyValue("Type"), Description));
}
}
return dictEntries;
}
public static bool EnumerateObjects(ManagementObject bcdStore, uint Type, out System.Management.ManagementBaseObject[] Objects)
{
System.Management.ManagementBaseObject inParams = null;
inParams = bcdStore.GetMethodParameters("EnumerateObjects");
inParams["Type"] = ((uint)(Type));
System.Management.ManagementBaseObject outParams = bcdStore.InvokeMethod("EnumerateObjects", inParams, null);
Objects = ((System.Management.ManagementBaseObject[])(outParams.Properties["Objects"].Value));
return System.Convert.ToBoolean(outParams.Properties["ReturnValue"].Value);
}
public static bool GetElement(ManagementObject bdcObject, uint Type, out System.Management.ManagementBaseObject Element)
{
System.Management.ManagementBaseObject inParams = null;
inParams = bdcObject.GetMethodParameters("GetElement");
inParams["Type"] = ((uint)(Type));
System.Management.ManagementBaseObject outParams = bdcObject.InvokeMethod("GetElement", inParams, null);
Element = ((System.Management.ManagementBaseObject)(outParams.Properties["Element"].Value));
return System.Convert.ToBoolean(outParams.Properties["ReturnValue"].Value);
}
}
要查询系统存储,我会调用这个函数。
Dictionary<string, string> StdOSEntries = BCDWMI.EnumerateObjectsByType(BCDWMI.BCDE_STANDARD_OS_ENTRY, String.Empty);
foreach (String guid in StdOSEntries.Keys)
Debug.WriteLine(String.Format("Id={0} {1}", guid, StdOSEntries[guid]));
答案 0 :(得分:1)
如果您需要了解您感兴趣的引导条目的类型值,可以使用bcdedit.exe查找该条目的GUID,然后在您的程序中加载该条目,将GUID放在ManagementPath中,就像您一样做:
ManagementPath BcdObjectPath = new ManagementPath("root\\WMI:BcdObject.Id=\"" + "{Guid goes here}" + "\",StoreFilePath='" + storePath + "'");
然后获取Type属性的值,如下所示:
uint Type = (uint)BcdObject["Type"];
Console.WriteLine("{0:X8}", Type);
如果bcdedit.exe显示“众所周知”的标识符,如{current}或{bootmgr},请使用this document将标识符映射到GUID。
您还可以通过编程方式枚举类型:
for (uint a = 1; a <= 10; a++) {
uint FirmwareType = 0x10100000 | a;
uint BootType = 0x10200000 | a;
uint LegacyType = 0x10300000 | a;
uint RealModeType = 0x10400000 | a;
}
将提供您在此处的标识符
public static readonly UInt32 BCDE_STANDARD_OS_ENTRY = 0x10200003;
public static readonly UInt32 BCDE_LEGACY_OS_ENTRY = 0x10300006;
有关如何形成这些标识符的说明,请参阅WMI documentation on BcdObject class。
答案 1 :(得分:0)
我找到了解决方案。几乎总是如此,它非常明显和简单。我只是将0x0作为Type传递给了调用。
Dictionary<string, string> StdOSEntries = BCDWMI.EnumerateObjectsByType(0, String.Empty);
这就是我得到的。
Id: {0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9} Type: 20100000
Id: {4636856e-540f-4170-a130-a84776f4c654} Type: 20100000
Id: {6efb52bf-1766-41db-a6b3-0ee5eff72bd7} Type: 20200003
Id: {7619dcc8-fafe-11d9-b411-000476eba25f} Type: 30000000
Id: {7619dcc9-fafe-11d9-b411-000476eba25f} Type: 10200003 Windows Setup
Id: {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e} Type: 20100000
Id: {7ff607e0-4395-11db-b0de-0800200c9a66} Type: 20200003 Hypervisor Settings
Id: {9dea862c-5cdd-4e70-acc1-f32b344d4795} Type: 10100002 Windows Boot Manager
Id: {a19f4228-8f0e-11e7-ac85-005056c00008} Type: 30000000
Id: {a1c5dee9-8f0e-11e7-ac85-005056c00008} Type: 10200003 WinPE x86
Id: {a20de869-8f0e-11e7-ac85-005056c00008} Type: 10200003 WinPE amd64
Id: {b2721d73-1db4-4c62-bf78-c548a880142d} Type: 10200005 Windows Memory Diagnostic
我的设备选项现在列出的类型为0x30000000。因此,如果我传递0x30000000,该函数将返回两个设备。