c/c++获取物理磁盘的消息

我想获取Windows的物理磁盘的消息,比如说大小,使用率,对应的卷的消息(物理磁盘不是C\D\E,物理磁盘是disk0、disk1这种)


#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
#include <iomanip> // 添加此头文件用于设置输出精度

#pragma comment(lib, "wbemuuid.lib")

int main() {
    HRESULT hres;

    // 初始化COM
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) {
        std::cerr << "无法初始化COM库。错误代码 = 0x"
            << std::hex << hres << std::endl;
        return 1; // 程序执行失败
    }

    // 设置通用COM安全级别
    hres = CoInitializeSecurity(
        nullptr,
        -1, // COM协商服务
        nullptr, // 身份验证服务
        nullptr, // 保留
        RPC_C_AUTHN_LEVEL_DEFAULT, // 默认身份验证级别
        RPC_C_IMP_LEVEL_IMPERSONATE, // 默认模拟级别
        nullptr, // 身份验证信息
        EOAC_NONE, // 附加功能
        nullptr // 保留
    );

    if (FAILED(hres)) {
        std::cerr << "无法初始化安全性。错误代码 = 0x"
            << std::hex << hres << std::endl;
        CoUninitialize(); // 反初始化COM
        return 1; // 程序执行失败
    }

    // 获取WMI的初始定位器
    IWbemLocator* pLoc = nullptr;

    hres = CoCreateInstance(
        CLSID_WbemLocator,
        nullptr,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator,
        (LPVOID*)&pLoc);

    if (FAILED(hres)) {
        std::cerr << "无法创建IWbemLocator对象。错误代码 = 0x"
            << std::hex << hres << std::endl;
        CoUninitialize();
        return 1; // 程序执行失败
    }

    IWbemServices* pSvc = nullptr;

    // 与当前用户连接到root\cimv2命名空间,并获取指向pSvc的IWbemServices指针进行调用
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // WMI命名空间对象路径
        nullptr, // 用户名。nullptr = 当前用户
        nullptr, // 用户密码。nullptr = 当前用户
        nullptr, // 区域设置。nullptr表示当前
        0, // 安全标志。
        nullptr, // 授权(例如Kerberos)
        nullptr, // 上下文对象
        &pSvc // 指向IWbemServices代理的指针
    );

    if (FAILED(hres)) {
        std::cerr << "无法连接。错误代码 = 0x"
            << std::hex << hres << std::endl;
        pLoc->Release();
        CoUninitialize();
        return 1; // 程序执行失败
    }

    std::cout << "已连接到ROOT\\CIMV2 WMI命名空间" << std::endl;

    // 设置WMI代理的安全级别,以便WMI服务处理调用
    hres = CoSetProxyBlanket(
        pSvc, // 指定要设置的代理
        RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
        RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
        nullptr, // 服务器主体名称
        RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        nullptr, // 客户端身份
        EOAC_NONE // 代理功能
    );

    if (FAILED(hres)) {
        std::cerr << "无法设置代理保护。错误代码 = 0x"
            << std::hex << hres << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1; // 程序执行失败
    }

    // 获取磁盘驱动器的数据
    IEnumWbemClassObject* pEnumerator = nullptr;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_DiskDrive"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        nullptr,
        &pEnumerator);

    if (FAILED(hres)) {
        std::cerr << "查询操作系统名称失败。错误代码 = 0x"
            << std::hex << hres << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1; // 程序执行失败
    }

    // 从查询中获取数据
    IWbemClassObject* pclsObj = nullptr;
    ULONG uReturn = 0;

    while (pEnumerator) {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

        if (0 == uReturn) {
            break;
        }

        VARIANT vtProp;

        // 获取驱动器的型号
        hr = pclsObj->Get(L"Model", 0, &vtProp, 0, 0);
        std::wcout << "型号: " << vtProp.bstrVal << std::endl;
        VariantClear(&vtProp);

        // 获取驱动器的大小
        hr = pclsObj->Get(L"Size", 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr) && vtProp.vt == VT_BSTR && vtProp.bstrVal != nullptr) {
            unsigned long long size = _wtoi64(vtProp.bstrVal);
            double sizeInGB = size / (1024.0 * 1024.0 * 1024.0);
            std::wcout << "大小: " << std::fixed << std::setprecision(2) << sizeInGB << " GB" << std::endl;
        }
        VariantClear(&vtProp);

        // 获取驱动器的序列号
        hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
        std::wcout << "序列号: " << vtProp.bstrVal << std::endl;
        VariantClear(&vtProp);

        pclsObj->Release();
    }

    // 获取分区和已使用空间
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM Win32_LogicalDisk"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        nullptr,
        &pEnumerator);

    while (pEnumerator) {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

        if (0 == uReturn) {
            break;
        }

        VARIANT vtProp;

        // 获取驱动器的名称(例如,C:\)
        hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
        std::wcout << "驱动器: " << vtProp.bstrVal << std::endl;
        VariantClear(&vtProp);

        // 获取驱动器的大小
        hr = pclsObj->Get(L"Size", 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr) && vtProp.vt == VT_BSTR && vtProp.bstrVal != nullptr) {
            unsigned long long size = _wtoi64(vtProp.bstrVal);
            double sizeInGB = size / (1024.0 * 1024.0 * 1024.0);
            std::wcout << "大小: " << std::fixed << std::setprecision(2) << sizeInGB << " GB" << std::endl;
        }
        VariantClear(&vtProp);

        // 获取已使用空间
        hr = pclsObj->Get(L"FreeSpace", 0, &vtProp, 0, 0);
        if (SUCCEEDED(hr) && vtProp.vt == VT_BSTR && vtProp.bstrVal != nullptr) {
            unsigned long long freeSpace = _wtoi64(vtProp.bstrVal);
            double freeSpaceInGB = freeSpace / (1024.0 * 1024.0 * 1024.0);
            std::wcout << "可用空间: " << std::fixed << std::setprecision(2) << freeSpaceInGB << " GB" << std::endl;
        }
        VariantClear(&vtProp);

        pclsObj->Release();
    }

    // 清理
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();

    return 0; // 程序成功完成
}

参考示例:https://peakchen.blog.csdn.net/article/details/131538134?spm=1001.2014.3001.5502

d:\test>PowerShell -Command "Get-PhysicalDisk"

Number FriendlyName          SerialNumber         MediaType CanPool OperationalStatus HealthStatus Usage            Size
------ ------------          ------------         --------- ------- ----------------- ------------ -----            ----
1      INTEL HBRPEKNX0202AL  5CD2_E456_9140_EA01. SSD       False   OK                Healthy      Auto-Select 476.94 GB
2      INTEL HBRPEKNX0202ALO 5CD2_E402_93E2_0100. SSD       False   OK                Healthy      Auto-Select  27.25 GB
0      HGST HUS726T4TALE6L4  V6J3XVLR             HDD       False   OK                Healthy      Auto-Select   3.64 TB



c/c++获取物理磁盘的消息

//  Sample output:
//  There is       51 percent of memory in use.
//  There are 2029968 total KB of physical memory.
//  There are  987388 free  KB of physical memory.
//  There are 3884620 total KB of paging file.
//  There are 2799776 free  KB of paging file.
//  There are 2097024 total KB of virtual memory.
//  There are 2084876 free  KB of virtual memory.
//  There are       0 free  KB of extended memory.
 
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
 
// Use to convert bytes to KB
#define DIV 1024
 
// Specify the width of the field in which to print the numbers. 
// The asterisk in the format specifier "%*I64d" takes an integer 
// argument and uses it to pad and right justify the number.
#define WIDTH 7
 
void _tmain()
{
  MEMORYSTATUSEX statex;
 
  statex.dwLength = sizeof (statex);
 
  GlobalMemoryStatusEx (&statex);
 
  _tprintf (TEXT("There is  %*ld percent of memory in use.\n"),
            WIDTH, statex.dwMemoryLoad);
  _tprintf (TEXT("There are %*I64d total KB of physical memory.\n"),
            WIDTH, statex.ullTotalPhys/DIV);
  _tprintf (TEXT("There are %*I64d free  KB of physical memory.\n"),
            WIDTH, statex.ullAvailPhys/DIV);
  _tprintf (TEXT("There are %*I64d total KB of paging file.\n"),
            WIDTH, statex.ullTotalPageFile/DIV);
  _tprintf (TEXT("There are %*I64d free  KB of paging file.\n"),
            WIDTH, statex.ullAvailPageFile/DIV);
  _tprintf (TEXT("There are %*I64d total KB of virtual memory.\n"),
            WIDTH, statex.ullTotalVirtual/DIV);
  _tprintf (TEXT("There are %*I64d free  KB of virtual memory.\n"),
            WIDTH, statex.ullAvailVirtual/DIV);
 
  // Show the amount of extended memory available.
 
  _tprintf (TEXT("There are %*I64d free  KB of extended memory.\n"),
            WIDTH, statex.ullAvailExtendedVirtual/DIV);
}

  • 以下回答由chatgpt基于相关博客总结生成:

    由于参考资料并没有给出相关获取磁盘信息的代码,我无法提供具体的解决方案。但是,我可以给你一些思路和提供一些用于获取磁盘信息的函数。

    1. 使用GetLogicalDrives函数获取系统上所有的逻辑驱动器列表。
    #include <iostream>
    #include <vector>
    #include <Windows.h>
    
    int main() {
        DWORD drives = GetLogicalDrives();
        std::vector<char> driveLetters;
    
        for (char i = 'A'; i <= 'Z'; i++) {
            if (drives & (1 << (i - 'A'))) {
                driveLetters.push_back(i);
            }
        }
    
        for (char driveLetter : driveLetters) {
            std::cout << driveLetter << ":" << std::endl;
        }
    
        return 0;
    }
    
    1. 使用GetDiskFreeSpaceEx函数获取磁盘的大小和使用率。
    #include <iostream>
    #include <Windows.h>
    
    int main() {
        ULARGE_INTEGER totalBytes;
        ULARGE_INTEGER freeBytes;
    
        if (GetDiskFreeSpaceExA("C:", &freeBytes, &totalBytes, nullptr)) {
            double totalSize = static_cast<double>(totalBytes.QuadPart) / (1024 * 1024 * 1024);  // 将字节转换为GB
            double freeSpace = static_cast<double>(freeBytes.QuadPart) / (1024 * 1024 * 1024);  // 将字节转换为GB
    
            double usageRate = (totalSize - freeSpace) / totalSize * 100;
    
            std::cout << "Total Size: " << totalSize << "GB" << std::endl;
            std::cout << "Free Space: " << freeSpace << "GB" << std::endl;
            std::cout << "Usage Rate: " << usageRate << "%" << std::endl;
        } else {
            std::cout << "Failed to get disk information." << std::endl;
        }
    
        return 0;
    }
    

    这些代码片段可以帮助你获取系统上的逻辑驱动器列表以及磁盘的大小和使用率。你可以根据你的需求进行修改和扩展。希望能对你有所帮助!

要获取Windows的物理磁盘的信息,你可以使用Windows Management Instrumentation (WMI) 接口来实现。

#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

int main(int argc, char** argv) {
    HRESULT hres;

    // 初始化COM库
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) {
        std::cout << "Failed to initialize COM library. Error code: " << hres << std::endl;
        return 1;
    }

    // 创建WMI接口工厂
    IWbemLocator* pLoc = NULL;
    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
    if (FAILED(hres)) {
        std::cout << "Failed to create IWbemLocator object. Error code: " << hres << std::endl;
        CoUninitialize();
        return 1;
    }

    // 连接WMI命名空间
    IWbemServices* pSvc = NULL;
    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
    if (FAILED(hres)) {
        std::cout << "Could not connect to WMI. Error code: " << hres << std::endl;
        pLoc->Release();
        CoUninitialize();
        return 1;
    }

    // 设置连接参数
    hres = 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 (FAILED(hres)) {
        std::cout << "Could not set proxy blanket. Error code: " << hres << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;
    }

    // 执行WMI查询
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(_bstr_t("WQL"), _bstr_t("SELECT * FROM Win32_DiskDrive"), WBEM_FLAG_FORWARD_ONLY, NULL, &pEnumerator);
    if (FAILED(hres)) {
        std::cout << "Failed to execute WQL query. Error code: " << hres << std::endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;
    }

    // 获取查询结果
    IWbemClassObject* pclsObj = NULL;
    ULONG uReturn = 0;
    while (pEnumerator) {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        if (0 == uReturn)
            break;

        VARIANT vtProp;
        hr = pclsObj->Get(L"DeviceID", 0, &vtProp, 0, 0);
        std::wstring deviceID(vtProp.bstrVal);
        VariantClear(&vtProp);

        hr = pclsObj->Get(L"Size", 0, &vtProp, 0, 0);
        unsigned long long size = vtProp.ullVal;
        VariantClear(&vtProp);

        hr = pclsObj->Get(L"StatusInfo", 0, &vtProp, 0, 0);
        UINT statusInfo = vtProp.uintVal;
        VariantClear(&vtProp);

        std::wcout << L"Device ID: " << deviceID << std::endl;
        std::wcout << L"Size: " << size << L" bytes" << std::endl;
        std::wcout << L"Status Info: " << statusInfo << std::endl;

        pclsObj->Release();
    }

    // 释放资源
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();

    return 0;
}

这段代码会获取所有物理磁盘的设备ID,大小和状态信息,并将其打印出来。你可以在这基础上扩展获取其他信息,如使用率和对应的卷信息。

请注意,在编译代码时,需要链接wbemuuid.lib库,并将编译器设置为支持C++11或更新版本

要获取Windows物理磁盘(例如disk0)的消息,你可以使用Windows API函数来实现。以下是一个使用C/C++编写的示例代码,可以获取物理磁盘的大小、使用率和对应的卷的消息:

#include <windows.h>
#include <stdio.h>

int main() {
    ULARGE_INTEGER totalSize, freeSpace;
    if (GetDiskFreeSpaceEx("C:\\", NULL, &totalSize, &freeSpace)) {
        double totalGB = totalSize.QuadPart / (1024.0 * 1024 * 1024);
        double freeGB = freeSpace.QuadPart / (1024.0 * 1024 * 1024);
        double usedGB = totalGB - freeGB;
        double usagePercentage = (usedGB / totalGB) * 100;

        printf("Disk: disk0\n");
        printf("Total Size: %.2f GB\n", totalGB);
        printf("Used Space: %.2f GB\n", usedGB);
        printf("Free Space: %.2f GB\n", freeGB);
        printf("Usage Percentage: %.2f%%\n", usagePercentage);
    }

    return 0;
}

这段代码使用了GetDiskFreeSpaceEx函数来获取指定驱动器的磁盘空间信息。然后,计算使用率并打印相关信息。