Qt 使用WINDOWS API读取SMBIOS信息,并通过CMD命令打印相关信息,参考DumpSMBIOS项目

在获取PE系统中的CPU、主板、内存信息时,发现使用WMI部分信息无法获取,通过gitGub上的DumpSMBIOS完全解决了这个问题,并单独做成了个案例,以下示例和代码都是参考DumpSMBIOS项目

SMBIOS这个数据还是用到的比较少。但是DumpSMBIOS项目有很多方面直接学习借鉴的东西。

目录

SMBIOS 读取

详见DumpSMBIOS源码,此处只是对修改的部分代码进行一个总结,关键代码的整理

结构体对齐

在DumpSMBIOS示例中,SMBIOS读取的数据有13种类型,每种都对应结构体,并使用
#pragma pack 对齐字节,对齐字节获取数据在Windows API中很常见。

也难怪面试总有人喜欢问数据类型占几个字节的问题,

在通信方面,结构体对齐读取数据流应该方便得多。

cpp 复制代码
#pragma pack(push)
#pragma pack(1)

#define WAKEUP_TYPE_COUNT   9
#define BOARD_TYPE_COUNT    13
typedef struct _RawSMBIOSData
{
    BYTE	Used20CallingMethod;
    BYTE	MajorVersion;
    BYTE	MinorVersion;
    BYTE	DmiRevision;
    DWORD	Length;
    PBYTE	SMBIOSTableData;
} RawSMBIOSData, *PRawSMBIOSData;

typedef struct _SMBIOSHEADER_
{
    BYTE Type;
    BYTE Length;
    WORD Handle;
} SMBIOSHEADER, *PSMBIOSHEADER;

typedef struct _TYPE_0_ {
    SMBIOSHEADER	Header;
    UCHAR	Vendor;
    UCHAR	Version;
    UINT16	StartingAddrSeg;
    UCHAR	ReleaseDate;
    UCHAR	ROMSize;
    ULONG64 Characteristics;
    UCHAR	Extension[2]; // spec. 2.3
    UCHAR	MajorRelease;
    UCHAR	MinorRelease;
    UCHAR	ECFirmwareMajor;
    UCHAR	ECFirmwareMinor;
} BIOSInfo, *PBIOSInfo;

typedef struct _TYPE_1_ {
    SMBIOSHEADER	Header;
    UCHAR	Manufacturer;
    UCHAR	ProductName;
    UCHAR	Version;
    UCHAR	SN;
    UCHAR	UUID[16];
    UCHAR	WakeUpType;
    UCHAR	SKUNumber;
    UCHAR	Family;
} SystemInfo, *PSystemInfo;

typedef struct _TYPE_2_ {
    SMBIOSHEADER	Header;
    UCHAR	Manufacturer;
    UCHAR	Product;
    UCHAR	Version;
    UCHAR	SN;
    UCHAR	AssetTag;
    UCHAR	FeatureFlags;
    UCHAR	LocationInChassis;
    UINT16	ChassisHandle;
    UCHAR	Type;
    UCHAR	NumObjHandle;
    UINT16	*pObjHandle;
} BoardInfo, *PBoardInfo;

typedef struct _TYPE_3_ {
    SMBIOSHEADER Header;
    UCHAR	Manufacturer;
    UCHAR	Type;
    UCHAR	Version;
    UCHAR	SN;
    UCHAR	AssetTag;
    UCHAR	BootupState;
    UCHAR	PowerSupplyState;
    UCHAR	ThermalState;
    UCHAR	SecurityStatus;
    ULONG32	OEMDefine;
    UCHAR	Height;
    UCHAR	NumPowerCord;
    UCHAR	ElementCount;
    UCHAR	ElementRecordLength;
    UCHAR	pElements;
} SystemEnclosure, *PSystemEnclosure;

typedef struct _TYPE_4_ {
    SMBIOSHEADER Header;
    UCHAR	SocketDesignation;
    UCHAR	Type;
    UCHAR	Family;
    UCHAR	Manufacturer;
    ULONG64 ID;
    UCHAR	Version;
    UCHAR	Voltage;
    UINT16	ExtClock;
    UINT16	MaxSpeed;
    UINT16	CurrentSpeed;
    UCHAR   Status;
    UCHAR   ProcessorUpgrade;
    UINT16  L1CacheHandle;
    UINT16  L2CacheHandle;
    UINT16  L3CacheHandle;
    UCHAR   SerialNumber;
    UCHAR   AssertTag;
    UCHAR   PartNumber;
    UCHAR   CoreCount;
    UCHAR   CoreEnabled;
    UCHAR   ThreadCount;
    UINT16  ProcessorCharacteristics;
    UINT16  ProcessorFamily2;

} ProcessorInfo, *PProcessorInfo;

typedef struct _TYPE_5_ {
    SMBIOSHEADER Header;
    // Todo, Here

} MemCtrlInfo, *PMemCtrlInfo;

typedef struct _TYPE_6_ {
    SMBIOSHEADER Header;
    UCHAR	SocketDesignation;
    UCHAR	BankConnections;
    UCHAR	CurrentSpeed;
    // Todo, Here
} MemModuleInfo, *PMemModuleInfo;

typedef struct _TYPE_7_ {
    SMBIOSHEADER Header;
    UCHAR	SocketDesignation;
    UINT16	Configuration;
    UINT16	MaxSize;
    UINT16	InstalledSize;
    UINT16	SupportSRAMType;
    UINT16	CurrentSRAMType;
    UCHAR	Speed;
    UCHAR	ErrorCorrectionType;
    UCHAR	SystemCacheType;
    UCHAR	Associativity;
} CacheInfo, *PCacheInfo;

typedef struct _TYPE_11_ {
    SMBIOSHEADER Header;
    UCHAR	Count;
} OemString, *POemString;

typedef struct _TYPE_17_ {
    SMBIOSHEADER Header;
    UINT16	PhysicalArrayHandle;
    UINT16	ErrorInformationHandle;
    UINT16	TotalWidth;
    UINT16	DataWidth;
    UINT16	Size;
    UCHAR	FormFactor;
    UCHAR	DeviceSet;
    UCHAR	DeviceLocator;
    UCHAR	BankLocator;
    UCHAR	MemoryType;
    UINT16	TypeDetail;
    UINT16	Speed;
    UCHAR	Manufacturer;
    UCHAR	SN;
    UCHAR	AssetTag;
    UCHAR	PN;
    UCHAR	Attributes;
} MemoryDevice, *PMemoryDevice;

typedef struct _TYPE_19_ {
    SMBIOSHEADER Header;
    ULONG32	Starting;
    ULONG32	Ending;
    UINT16	Handle;
    UCHAR	PartitionWidth;
} MemoryArrayMappedAddress, *PMemoryArrayMappedAddress;

typedef struct _TYPE_21_ {
    SMBIOSHEADER Header;
    UCHAR Type;
    UCHAR Interface;
    UCHAR NumOfButton;
} BuiltinPointDevice, *PBuiltinPointDevice;

typedef struct _TYPE_22_ {
    SMBIOSHEADER Header;
    UCHAR	Location;
    UCHAR	Manufacturer;
    UCHAR	Date;
    UCHAR	SN;
    UCHAR	DeviceName;
    UCHAR   Chemistry;
    UINT16  DesignCapacity;
    UINT16  DesignVoltage;
    UCHAR   SBDSVersionNumber;
    UCHAR   MaximumErrorInBatteryData;
    UINT16  SBDSSerialNumber;
    UINT16	SBDSManufactureDate;
    UCHAR   SBDSDeviceChemistry;
    UCHAR   DesignCapacityMultiplie;
    UINT32  OEM;
} PortableBattery, *PPortableBattery;
#pragma pack(pop)

读取SMBIOS数据

DumpSMBIOS使用两种方式读取SMBIOS数据
GetSystemFirmwareTableWMI

GetSystemFirmwareTable

使用 GetSystemFirmwareTable 函数读取原始 SMBIOS 固件表

cpp 复制代码
void Lib_Smbios::initialization()
{
    //	GET_SYSTEM_FIRMWARE_TABLE pGetSystemFirmwareTable = (GET_SYSTEM_FIRMWARE_TABLE)GetProcAddress(GetModuleHandle(L"kernel32"), "GetSystemFirmwareTable");

    LPBYTE pBuff = NULL;

    PBYTE tableStart = nullptr;
    UINT nTableLength = 0;
    DWORD needBufferSize = 0;


    const DWORD Signature = 'RSMB';
#if 0
    DWORD Signature = 'R';
    Signature = (Signature << 8) + 'S';
    Signature = (Signature << 8) + 'M';
    Signature = (Signature << 8) + 'B';
#endif

    //从固件表提供程序检索指定的固件表。
    //https://learn.microsoft.com/zh-cn/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable
    needBufferSize = GetSystemFirmwareTable(Signature, 0, NULL, 0);
    pBuff = new BYTE[needBufferSize];

    needBufferSize = GetSystemFirmwareTable(Signature, 0,pBuff,needBufferSize);
    if (needBufferSize > 0) {
        const PRawSMBIOSData pDMIData = (PRawSMBIOSData)pBuff;
        MajorVersion = pDMIData->MajorVersion;
        MinorVersion = pDMIData->MinorVersion;
        DMIRevision = pDMIData->DmiRevision;

        tableStart = (PBYTE) & (pDMIData->SMBIOSTableData);
        nTableLength = pDMIData->Length;
    }

    if ((0 == needBufferSize) || (nTableLength > needBufferSize))
    {
        if (getWmiSmbios(&pBuff, &nTableLength))
            tableStart = pBuff;
    }

    if (tableStart)
        ParseSMBIOSStruct(tableStart, nTableLength);

    if (pBuff)
        delete[] pBuff;
}
WMI

使用 WMI 检索 SMBIOS 属性。 Win32 类中包含许多单独的属性。 还可以使用 MSSMBios_RawSMBiosTables 类在单个缓冲区中检索原始 SMBIOS 数据。

cpp 复制代码
bool Lib_Smbios::getWmiSmbios(BYTE ** data, UINT * length)
{
    IWbemServices *  pSvc = NULL;
    IWbemServices *  pSvcSmbios = NULL;
    IWbemLocator *   pLoc = NULL;
    HRESULT            result;
    IEnumWbemClassObject *  pEnumerator = NULL;
    std::wostringstream     query;
    std::wstring            q;
    IWbemClassObject *      pInstance = NULL;
    VARIANT                 vtProp;
    ULONG                   uReturn = 0;
    CIMTYPE                 pvtType;

    result = CoInitialize(NULL);

    if (!SUCCEEDED(result))
        return false;

    result = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
    if (!SUCCEEDED(result)) {
        CoUninitialize();
        return false;
    }

    result = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc);
    if (!SUCCEEDED(result)) {
        CoUninitialize();
        return false;
    }

    result = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
    if (!SUCCEEDED(result)) {
        pLoc->Release();
        CoUninitialize();
        return false;
    }

    result = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
    if (!SUCCEEDED(result)) {
        pLoc->Release();
        CoUninitialize();
        return false;
    }

    result = pLoc->ConnectServer(_bstr_t(L"ROOT\\WMI"), NULL, NULL, 0, NULL, 0, 0, &pSvcSmbios);
    if (!SUCCEEDED(result)) {
        pLoc->Release();
        CoUninitialize();
        return false;
    }

    result = CoSetProxyBlanket(pSvcSmbios, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
    if (!SUCCEEDED(result)) {
        pSvcSmbios->Release();
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
    }

    result = pSvcSmbios->CreateInstanceEnum(bstr_t(L"MSSMBios_RawSMBiosTables"), 0, NULL, &pEnumerator);
    if (SUCCEEDED(result)) {
        while (pEnumerator) {
            result = pEnumerator->Next(WBEM_INFINITE, 1, &pInstance, &uReturn);

            if (!uReturn) {
                break;
            }
            VariantInit(&vtProp);
            result = pInstance->Get(bstr_t("SMBiosData"), 0, &vtProp, &pvtType, NULL);
            if (SUCCEEDED(result)) {
                SAFEARRAY * array = V_ARRAY(&vtProp);

                *length = array->rgsabound[0].cElements;
                *data = new BYTE[*length];
                memcpy(*data, (BYTE*)array->pvData, *length);
                VariantClear(&vtProp);
            }
        }
        pEnumerator->Release();
        if (pInstance)
            pInstance->Release();
    }

    if (pSvcSmbios)
        pSvcSmbios->Release();
    if (pSvc)
        pSvc->Release();
    if (pLoc)
        pLoc->Release();

    CoUninitialize();
    return true;
}

自定义结构体 - 实际获取数据结构

DumpSMBIOS项目中打印的字段封装成结构体,转换数据时保存,不只是输出内容

cpp 复制代码
#pragma region "获取 SMBIOS 指定数据(指定结构转换)" {

typedef struct _W_TYPE_0_ {
    PWCHAR Vendor;
    PWCHAR Version;
    PWCHAR Date;
    //pBIOS->Header.Length > 0x14
    DWORD SysVersion=0;
    DWORD ECVersion=0;
}W_BIOSInfo;

typedef struct _W_TYPE_1_
{
    PWCHAR Manufactor;
    PWCHAR ProductName;
    PWCHAR Version;
    PWCHAR SerialNumber;
    //pSystem->Header.Length > 0x08
    UUID SysUUID;
    //pSystem->Header.Length > 0x19
    PWCHAR SysSKU;
    PWCHAR SysFamily;
}W_SystemInfo;

typedef struct _W_TYPE_2_
{
    PWCHAR Manufacturer;
    PWCHAR Product;
    PWCHAR Version;
    PWCHAR SN;
    PWCHAR AssetTag;
    UCHAR FeatureFlags;
    //pBoard->Header.Length > 0x08
    PWCHAR LocationInChassis;
    //pBoard->Header.Length > 0x0B
    PWCHAR BoardType;
}W_BoardInfo;

typedef struct _W_TYPE_3_
{
    PWCHAR Manufacturer;
    PWCHAR Version;
    PWCHAR SN;
    PWCHAR AssetTag;
}W_SystemEnclosure;

typedef struct _W_TYPE_4_
{
    PWCHAR SocketDesignation;
    PWCHAR ProcessType;
    PWCHAR Family;
    PWCHAR Manufacturer;

    PWCHAR Version;
    PWCHAR Voltage;
    UINT16	ExtClock;
    UINT16	MaxSpeed;
    UINT16	CurrentSpeed;
    UCHAR   Status;

}W_ProcessorInfo;


typedef struct _W_TYPE_6_
{
    PWCHAR SocketDesignation;
    PWCHAR BankConnections;
    quint64 CurrentSpeed;

} W_MemModuleInfo;


typedef struct _W_TYPE_7_
{
    PWCHAR SocketDesignation;

} W_CacheInfo;

typedef struct _W_TYPE_11_
{
    QList<PWCHAR> datas;

} W_OemString;

typedef struct _W_TYPE_17_
{
    quint64 TotalWidth;
    quint64 DataWidth;
    PWCHAR  DeviceLocator;
    PWCHAR  BankLocator;
    PWCHAR  MemoryType;
    //pMD->Header.Length > 0x15
    quint64 Speed;
    PWCHAR	Manufacturer;
    PWCHAR	SN;
    PWCHAR	AssetTag;
    PWCHAR	PN;
    quint64 Size;

} W_MemoryDevice;


typedef struct _W_TYPE_21_
{
    PWCHAR  BuiltinPointDeviceType;
    PWCHAR  BuiltinPointDeviceInterface;
    quint64  NumOfButton;

} W_BuiltinPointDevice;


typedef struct _W_TYPE_22_
{
    PWCHAR Location;
    PWCHAR Manufacturer;
    //pPB->Date != 0
    PWCHAR Date;
    //pPB->SN != 0
    PWCHAR SN;

    PWCHAR DeviceName;

    //(pPB->Chemistry != 2)
    PWCHAR Chemistry;
    PWCHAR SBDSDeviceChemistry;

    quint64 DesignCapacity;
    quint64 DesignCapacityMultiplie;
    quint64 DesignVoltage;
    PWCHAR SBDSVersionNumber;
    quint64 MaximumErrorInBatteryData;
    quint64 SBDSSerialNumber;

} W_PortableBattery;

#pragma endregion }

结构体数据转换

其中需要注意的是 CP_ACP 与 CP_OEMCP 的使用,

测试时使用CP_OEMCP数据乱码,

但是 DumpSMBIOS 项目中使用 CP_OEMCP输出正常,脑壳痛。

cpp 复制代码
static const char* LocateStringA(const char* str, UINT i)
{
    static const char strNull[] = "";

    if (0 == i || 0 == *str) return strNull;

    while (--i)
    {
        str += strlen((char*)str) + 1;
    }
    return str;
}

#define GetData(_STR_,_IN_VAL_,_OUT_VAL_,val)                                       \
{                                                                                   \
    const char* c_##val = LocateStringA(_STR_, _IN_VAL_);                           \
    const int n_##val = (int) strlen(c_##val);                                      \
    _OUT_VAL_= new WCHAR[n_##val + 1];                                              \
    if (_OUT_VAL_)                                                                  \
{                                                                               \
    SecureZeroMemory(_OUT_VAL_, sizeof(WCHAR) * (n_##val + 1));                 \
    MultiByteToWideChar(CP_ACP, NULL, c_##val, n_##val, _OUT_VAL_, n_##val + 1);\
    }                                                                               \
    }

//将UChat转换为PWCHAR数据
bool Lib_Smbios::ProcBIOSInfo(Lib_Smbios* T, void* p)
{
    PBIOSInfo pBIOS = (PBIOSInfo)p;
    const char* str = toPointString(p);
    //后面使用宏定义 GetData 替换此处代码
    //    const char* Vendor = LocateStringA(str, pBIOS->Vendor);
    //    const char* Version = LocateStringA(str, pBIOS->Version);
    //    const char* Date = LocateStringA(str, pBIOS->ReleaseDate);
    //    const int nVendor = (int) strlen(Vendor);
    //    const int nVersion = (int) strlen(Version);
    //    const int nDate = (int) strlen(Date);

    //    T->DATA_BIOSInfo.Vendor= new WCHAR[nVendor + 1];
    //    T->DATA_BIOSInfo.Version= new WCHAR[nVersion + 1];
    //    T->DATA_BIOSInfo.Date= new WCHAR[nDate + 1];

    //    if (T->DATA_BIOSInfo.Vendor)
    //    {
    //        SecureZeroMemory(T->DATA_BIOSInfo.Vendor, sizeof(WCHAR) * (nVendor + 1));
    //        MultiByteToWideChar(CP_ACP, NULL, Vendor, nVendor, T->DATA_BIOSInfo.Vendor, nVendor + 1);
    //    }
    //    if (T->DATA_BIOSInfo.Version)
    //    {
    //        SecureZeroMemory(T->DATA_BIOSInfo.Version, sizeof(WCHAR) * (nVersion + 1));
    //        MultiByteToWideChar(CP_ACP, NULL, Version, nVersion, T->DATA_BIOSInfo.Version, nVersion + 1);
    //    }
    //    if (T->DATA_BIOSInfo.Date)
    //    {
    //        SecureZeroMemory(T->DATA_BIOSInfo.Date, sizeof(WCHAR) * (nDate + 1));
    //        MultiByteToWideChar(CP_ACP, NULL, Date, nDate, T->DATA_BIOSInfo.Date, nDate + 1);
    //    }

    GetData(str,pBIOS->Vendor,T->DATA_BIOSInfo.Vendor,Vendor);
    GetData(str,pBIOS->Version,T->DATA_BIOSInfo.Version,Version);
    GetData(str,pBIOS->ReleaseDate,T->DATA_BIOSInfo.Date,Date);

    if (pBIOS->Header.Length > 0x14)
    {
        T->DATA_BIOSInfo.SysVersion = pBIOS->MajorRelease << 16 | pBIOS->MinorRelease;
        T->DATA_BIOSInfo.ECVersion = pBIOS->ECFirmwareMajor << 16 | pBIOS->ECFirmwareMinor;
    }



if(Isprint){
    _tprintf(TEXT("%s\n"), getHeaderString(0));
    _tprintf(TEXT("Vendor: %s\n"), T->DATA_BIOSInfo.Vendor);
    _tprintf(TEXT("Version: %s\n"), T->DATA_BIOSInfo.Version);
    _tprintf(TEXT("BIOS Starting Segment: 0x%X\n"), pBIOS->StartingAddrSeg);
    _tprintf(TEXT("Release Date: %s\n"), T->DATA_BIOSInfo.Date);
    _tprintf(TEXT("Image Size: %dK\n"), (pBIOS->ROMSize + 1) * 64);
    if (pBIOS->Header.Length > 0x14)
    {   // for spec v2.4 and later
        _tprintf(TEXT("System BIOS version: %d.%d\n"), pBIOS->MajorRelease, pBIOS->MinorRelease);
        _tprintf(TEXT("EC Firmware version: %d.%d\n"), pBIOS->ECFirmwareMajor, pBIOS->ECFirmwareMinor);
    }
}


    return true;
}

参考示例链接

【SMBIOS数据结构和信息】读取参考示例链接:
https://github.com/KunYi/DumpSMBIOS
SMBIOS获取system bios ec cpu memory等相关信息
SMBIOS 规范定义了将进入与系统相关的数据结构的数据结构和信息
SMBIOS | DMTF规范

QT CMD命令行输出

之前看到某些软件既可以CMD命令行输出数据,又可以打开界面操作的时候,我就尝试过使用QT实现类似的功能。

通过console控制台程序与可执行程序放在同级目录实现,如果argc参数个数大于1就是console打印数据,否则就打开同级目录下的可执行程序,但是这样一来启动的可执行程序的时候始终会有console控制台程序一闪而逝。这个问题始终没有解决、、、

其他方法 隐藏控制台窗体

通过在main.cpp添加这段,确实能隐藏console打开,但是需要的console输出内容就没了,这只适用于隐藏不显示console控制台。

cpp 复制代码
//Qt 隐藏控制台窗体
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

通过ShowWindow隐藏控制台也只是加快了隐藏的速度,还是能看见console控制台程序一闪而逝。

cpp 复制代码
  HWND consoleWindow = GetConsoleWindow(); // 获取控制台窗口句柄
  // 隐藏窗口
  ShowWindow(consoleWindow, SW_HIDE);

值得注意的是如果需要打印数据后自动退出程序就需要修改main的返回值
完整示例:

cpp 复制代码
//Qt 隐藏控制台窗体
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    if(argc==1)
    {
        HWND consoleWindow = GetConsoleWindow(); // 获取控制台窗口句柄
        // 隐藏窗口
        ShowWindow(consoleWindow, SW_HIDE);

        QProcess* process=new QProcess();
        process->startDetached("Computer_INFO.exe");
        process->waitForStarted(-1);
    }
    else
    {
        Lib_Command_Out out;
        out.OpeaType(argc, argv);
    }

    //退出事件循环
    //https://blog.csdn.net/qq_21078557/article/details/89959755
    a.exit(0);
    return 0;
    //    return a.exec();
}

可执行程序示例 :

CMD输入示例:

cpp 复制代码
SMBIOS数据查询小工具命令行:
================================
*-V                       显示命令行参数
 -S [-I] [filepath]          打印出SMBIOS的所有详细信息,具体内容参考GitHub上DumpSMBIOS开源项目,
                             可选参数[-I] 输出INI格式文件 ,
                             可选参数[filepath] 设置输出路径,没有则默认exe路径中生成[SMBIOS.INI]文件
 -D [-I] [filepath]          打印硬盘相关信息[同上可选]
 -VS [-I] [filepath]         打印卷/盘符相关信息[同上可选]*

///C:\Users\admin\Desktop\SMBIOS_READ.exe -v 输出:

==========          BIOS information           ==========
Vendor: American Megatrends Inc.
Version: 1005
BIOS Starting Segment: 0xF000
Release Date: 08/07/2019
Image Size: 16384K
System BIOS version: 5.12
EC Firmware version: 255.255
==========         System information          ==========
Manufacturer: System manufacturer
Product Name: System Product Name
Version: System Version
Serial Number: System Serial Number
UUID: F9824375-C4FB-4D1E-E715-D45D641D7A2A
Wake-up Type: Power Switch
SKU Number: SKU
Family: To be filled by O.E.M.
==========       Base Board information        ==========
Length: 0xF
Manufacturer: ASUSTeK COMPUTER INC.
Product Name: PRIME H310M-K R2.0
Version: Rev X.0x
Serial Number: 191262638910697
Asset Tag Number: Default string
Feature Flag: 0x9
Location in Chassis: Default string
Board Type: Processor/Memory Module
Number of Contained Object Handles: 0
Object Handles:

==========    System Enclosure information     ==========
Length: 0x16
Manufacturer: Default string
Version: Default string
Serial Number: Default string
Asset Tag Number: Default string
==========             OEM String              ==========
Count: 8
OEM String1: Default string
OEM String2: Default string
OEM String3: OLEANDER V2
OEM String4: Default string
OEM String5: FFFFFFFFFFFFF
OEM String6: FFFFFFFFFFFFF
OEM String7: FFFFFFFFFFFFF
OEM String8: Default string
==========            Memory Device            ==========
Length: 0x28
Total Width: 64bits
Data Width: 64bits
Device Locator: ChannelA-DIMM1
Bank Locator: BANK 0
Memory Type: DDR4
Size: 8192M
Speed: 2666
Manufacturer: CRUCIAL
Serial Number: 22AD9C80
Asset Tag Number: 9876543210
Part Number: CT8G4DFS8266.M8FE
==========            Memory Device            ==========
Length: 0x28
Total Width: 64bits
Data Width: 64bits
Device Locator: ChannelB-DIMM1
Bank Locator: BANK 2
Memory Type: DDR4
Size: 8192M
Speed: 2666
Manufacturer: CRUCIAL
Serial Number: 25ACA8B3
Asset Tag Number: 9876543210
Part Number: CT8G4DFS8266.M8FD
==========     Memory Array Mapped Address     ==========
Length: 0x1F
Starting Address: 0x00000000
Ending Address: 0x00FFFFFF
Memory Array Handle: 0x36
Partition Width: 0x2
==========           Cache information         ==========
Length: 0x1B
Socket Designation: L1 Cache
==========           Cache information         ==========
Length: 0x1B
Socket Designation: L2 Cache
==========           Cache information         ==========
Length: 0x1B
Socket Designation: L3 Cache
==========        Processor information        ==========
Length: 0x30
Socket Designation: LGA1151
Processor Type: Math Processor
Processor Family: 
Processor ID:
Processor Manufacturer: Intel(R) Corporation
Processor Voltage: es|ES|iso8859-1
Processor Version: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
External Clock: 100MHz, 0MHz is unknown clock
Max Speed: 8300MHz
Current Speed: 2900MHz
Status: 0x41

双击打开 -执行程序:

相关推荐
用户8055336980315 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner16 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner9 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner10 天前
DicomViewer (目录调整) 2
qt
xcyxiner10 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
qq_3692243312 天前
Windows全系通用!ntdll.dll文件丢失、报错、闪退问题的完整排查与修复教程
windows·dll·dll修复·dll丢失·dll错误
桥田智能12 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构