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

在获取PE系统中的CPU、主板、内存信息时,发现使用WMI部分信息无法获取,通过gitGub上的DumpSMBIOS完全解决了这个问题,并单独做成了个案例,以下示例和代码都是参考DumpSMBIOS项目
SMBIOS这个数据还是用到的比较少。但是DumpSMBIOS项目有很多方面直接学习借鉴的东西。

目录

    • SMBIOS 读取
      • 结构体对齐
      • 读取SMBIOS数据
        • GetSystemFirmwareTable
        • WMI
      • 自定义结构体 - 实际获取数据结构
      • 结构体数据转换
      • 参考示例链接
    • QT CMD命令行输出
      • 其他方法 隐藏控制台窗体
      • 可执行程序示例 :

SMBIOS 读取

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

结构体对齐

在DumpSMBIOS示例中,SMBIOS读取的数据有13种类型,每种都对应结构体,并使用
#pragma pack 对齐字节,对齐字节获取数据在Windows API中很常见。
也难怪面试总有人喜欢问数据类型占几个字节的问题,
在通信方面,结构体对齐读取数据流应该方便得多。

#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 固件表

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 数据。

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项目中打印的字段封装成结构体,转换数据时保存,不只是输出内容

#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输出正常,脑壳痛。

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控制台。

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

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

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

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

//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输入示例:

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

双击打开 -执行程序:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/304543.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

系列十四、理解MySQL varchar(50)

一、理解MySQL varchar(50) 1.1、概述 日常开发中&#xff0c;数据库建表是必不可少的一个环节&#xff0c;建表的时候通常会看到设定某个字段的长度为varchar(50)&#xff0c;例如如下建表语句&#xff1a; 那么怎么理解varchar(50)&#xff1f;这个分情况的&#xff0c;MySQ…

基于SpringBoot的教学管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

Linux Capabilities 进阶实战

目录 1. 快速回顾 2. 为可执行文件分配 capabilities 3. 构建半特权环境 4. 容器与 capabilities Linux Capabilities 基础概念与基本使用 上一篇学习了LinuxCapabilities的基础知识和基本使用&#xff0c;因为后面需要学习Docker的逃逸&#xff0c;理解Linux Capabilitie…

Three.js基础入门介绍——Three.js学习五【让模型沿着轨迹移动】

流程 基本流程 添加模型增加运动轨迹让模型沿轨迹运动 工程文件结构如下图&#xff1a; static&#xff1a;存放静态资源文件three.js-master&#xff1a;为官网下载的代码包&#xff0c;包含所有需要用到的资源包&#xff0c;链接&#xff1a;https://github.com/mrdoob/thr…

Java异常处理--异常处理概述与常见异常举例

文章目录 一、异常概述1- 什么是生活的异常2- 什么是程序的异常3- 异常的抛出机制4- 如何对待异常 二、Java异常体系1- Throwable2- Error 和 Exception1、Error1.1 介绍1.2 举例 2、Exception2.1 介绍2.2 编译时异常和运行时异常 3- Java异常体系结构1、体系结构2、运行时异常…

用Python来制作一个微信聊天机器人

1. 效果展示 通过本地搭建一个flask服务器来接收信息&#xff0c;这里我简单使用展示&#xff0c;就没有对接收的信息进行处理了。 信息接收展示 发送信息展示 这里就直接使用python发送一个post请求即可&#xff0c;可以发送文字或者图片 代码展示 接收信息 #!/usr/bin/e…

JAVA:解析Event事件机制与应用举例

1、简述 Java事件机制是一种基于观察者模式的设计模式&#xff0c;用于处理对象之间的松耦合通信。本篇技术博客将深入探讨Java事件机制的原理&#xff0c;并通过实际应用举例展示如何在项目中灵活利用该机制。 2、基本原理 Java事件机制基于观察者模式&#xff0c;包含以下…

nacos源码本地调试

1&#xff1a;源码克隆 github地址&#xff1a;https://github.com/alibaba/nacos.git gitee镜像地址&#xff1a;https://gitee.com/mirrors/Nacos.git 本文通过IntelliJ IDEA 2023.3.2 (Ultimate Edition)构建&#xff0c;nacos版本为2.3.1 2&#xff1a;首先clone 等待…

作业--day42

界面设计 MyProWin::MyProWin(QWidget *parent): QMainWindow(parent) {/**********窗口主体**********///窗口大小this->setFixedSize(644, 493);this->setWindowTitle("QQ");this->setWindowIcon(QIcon("C:/Users/10988/Downloads/pictrue/pictrue/…

机器学习指南:如何学习机器学习?

机器学习 一、介绍 你有没有想过计算机是如何从数据中学习和变得更聪明的&#xff1f;这就是机器学习 &#xff08;ML&#xff09; 的魔力&#xff01;这就像计算机科学和统计学的酷炫组合&#xff0c;计算机从大量信息中学习以解决问题并做出预测&#xff0c;就像人类一样。 …

【Java EE初阶九】多线程案例(线程池)

一、线程池的引入 引入池---->主要是为了提高效率&#xff1b; 最开始&#xff0c;进程可以解决并发编程的问题&#xff0c;但是代价有点大了&#xff0c;于是引入了 “轻量级进程” ---->线程 线程也能解决并发编程的问题&#xff0c;而且线程的开销比进程要小的多&…

分布式I/O应用于智慧停车场的方案介绍

客户案例背景 目前车位检测技术有磁电技术、超声波技术、红外线技术、图像识别车位技术。考虑到例如电磁干扰、信号干扰等的环境因素影响&#xff0c;通常会采用组合使用的方式进行&#xff0c;如采用不同的传感器、应用不同的协议等&#xff0c;以便提高车位检测的准确性和实时…

R语言频率分布直方图绘制教程

本篇笔记分享R语言绘制直方图的方法&#xff0c;通过多种展示风格对数据进行可视化&#xff0c;主要用到ggplot、ggpubr等包。 什么是直方图&#xff1f; 直方图(Histogram)&#xff0c;又称质量分布图&#xff0c;是一种统计报告图&#xff0c;由一系列高度不等的柱子表示数…

现代 C++ 及 C++ 的演变

C 活跃在程序设计领域。该语言写入了许多新项目&#xff0c;而且据 TIOBE 排行榜数据显示&#xff0c;C 的受欢迎度和使用率位居第 4&#xff0c;仅次于 Python、Java 和 C。 尽管 C 在过去二十年里的 TIOBE 排名都位居前列&#xff08;2008 年 2 月排在第 5 名&#xff0c;到…

从0开始python学习-46.pytest框架之通过yaml处理接口关联问题-针对变量处理

目录 1. 提取变量 1.1 提取方法 1.2 提取地方&#xff1a;响应的body&#xff0c;响应的cookie&#xff0c;响应头 1.3 提取方式&#xff1a; 1.4 示例&#xff1a;在能获取到对应token的yaml用例中写入 2.使用变量&#xff1a;封装一个通用extract_util.py 3. 调用测试用…

设计模式之过滤器模式

目录 1.简介 2.过滤器的实现 2.1.过滤器的角色 2.2.类图 2.3.具体实现 3.过滤器模式的优点 4.过滤器模式的不足 5.适用的场景 1.简介 过滤器模式&#xff08;Filter Pattern&#xff09;或标准模式&#xff08;Criteria Pattern&#xff09;是一种结构型设计模式&…

5.5 THREAD GRANULARITY

性能调优中一个重要的算法决定是线程的粒度。有时&#xff0c;在每个线程中投入更多工作并使用更少的线程是有利的。当线程之间存在一些冗余工作时&#xff0c;就会产生这种优势。在当前一代设备中&#xff0c;每个SM的指令处理带宽有限。每个指令都消耗指令处理带宽&#xff0…

迎接人工智能的下一个时代:ChatGPT的技术实现原理、行业实践以及商业变现途径

课程背景 2023年&#xff0c;以ChatGPT为代表的接近人类水平的对话机器人&#xff0c;AIGC不断刷爆网络&#xff0c;其强大的内容生成能力给人们带来了巨大的震撼。学术界和产业界也都形成共识&#xff1a;AIGC绝非昙花一现&#xff0c;其底层技术和产业生态已经形成了新的格局…

【数据结构 | 二叉树入门】

数据结构 | 二叉树入门 二叉树概念&#xff1a;二叉树特点&#xff1a;二叉树的基本形态特殊二叉树满二叉树完全二叉树 二叉树的存储结构二叉树的遍历先序遍历中序遍历后序遍历 计算二叉树的节点个数计算叶子节点的个数树的高度求第k层节点个数 二叉树概念&#xff1a; 如下图…

【51单片机】延时函数delay的坑——关于无符号整型数据for语句“x >= 0“变成死循环

请认真看看以下延时函数是否正确&#xff0c;并且指出错误&#xff1a;&#xff08;考考C语言功底&#xff09; void delay_ms(unsigned int xms) //delay x ms {unsigned int x,y;for(xxms;x>0;x--)for(y124;y>0;y--); }废话少说&#xff0c;上正确代码&#xff1a; v…