weixin_46027762 2023-07-04 15:32 采纳率: 64.7%
浏览 140
已结题

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

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

  • 写回答

7条回答 默认 最新

  • PhoenixRiser 2023-07-04 18:19
    关注
    
    #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; // 程序成功完成
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 7月13日
  • 已采纳回答 7月5日
  • 创建了问题 7月4日

悬赏问题

  • ¥15 安霸cv22 + rtl8211f 千兆,udp传输丢包
  • ¥15 关于区块链和边缘环境搭建的相关问题
  • ¥15 windows远程桌面断卡重连软件卡顿问题
  • ¥30 Unity 实现扫描效果
  • ¥15 HbuilderX检测不到安卓模拟器
  • ¥15 这个main已经在filename.obj中定义是什么错 C语言
  • ¥15 关于#linux#的问题:exsi8.0系统 怎么更改web访问端口,不用80、443
  • ¥15 使用elementor设计样式
  • ¥15 谁能提供一个中文版的推销咨询网站连接?
  • ¥15 springboot项目程序启动报错