【问题标题】:WMI CPUTemp Always Returns Same ValueWMI CPUTemp 总是返回相同的值
【发布时间】:2017-06-16 09:03:19
【问题描述】:

我正在尝试从 WMI 获取 CPU 的温度。但是当我从管理员命令提示符处执行代码时。它总是返回相同的值;

CPU = 39.050000 C”。

我不知道我在哪里犯了错误。我的操作系统是 Windows 10 64 位,我使用 Visual Studio 2017 15.1。我在 C# 上编写了相同的代码,它返回相同的值也只是 39。我做了一些研究,但我仍然不确定如何解决这个问题。

  #define _WIN32_DCOM
    #include <iostream>
    #include "stdafx.h"
    using namespace std;
    #include <comdef.h>
    #include <Wbemidl.h>

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

HRESULT GetCpuTemperature(LPLONG pTemperature)
{
    if (pTemperature == NULL)
        return E_INVALIDARG;

    *pTemperature = -1;
    HRESULT ci = CoInitialize(NULL);
    HRESULT hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
    if (SUCCEEDED(hr))
    {
        IWbemLocator *pLocator;
        hr = CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLocator);
        if (SUCCEEDED(hr))
        {
            IWbemServices *pServices;
            BSTR ns = SysAllocString(L"root\\WMI");
            hr = pLocator->ConnectServer(ns, NULL, NULL, NULL, 0, NULL, NULL, &pServices);
            pLocator->Release();
            SysFreeString(ns);
            if (SUCCEEDED(hr))
            {
                BSTR query = SysAllocString(L"SELECT * FROM MSAcpi_ThermalZoneTemperature");
                BSTR wql = SysAllocString(L"WQL");
                IEnumWbemClassObject *pEnum;
                hr = pServices->ExecQuery(wql, query, WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
                SysFreeString(wql);
                SysFreeString(query);
                pServices->Release();
                if (SUCCEEDED(hr))
                {
                    IWbemClassObject *pObject;
                    ULONG returned;
                    hr = pEnum->Next(WBEM_INFINITE, 1, &pObject, &returned);
                    pEnum->Release();
                    if (SUCCEEDED(hr))
                    {
                        BSTR temp = SysAllocString(L"CurrentTemperature");
                        VARIANT v;
                        VariantInit(&v);
                        hr = pObject->Get(temp, 0, &v, NULL, NULL);
                        pObject->Release();
                        SysFreeString(temp);
                        if (SUCCEEDED(hr))
                        {
                            *pTemperature = V_I4(&v);
                        }
                        VariantClear(&v);
                    }
                }
            }
            if (ci == S_OK)
            {
                CoUninitialize();
            }
        }
    }
    return hr;
}

这是我的主要代码

int main(int argc, char **argv)
{
    LONG temp;
    GetCpuTemperature(&temp);
    printf("CPU = %lf °C\n", ((double)temp / 10 - 273.15));
    getc(stdin);
    return 0;
}

编辑:错误信息。

【问题讨论】:

  • VARIANT 值是否有 I4 类型?
  • 我不确定。我是这门语言的新手。但还有另一件事;它在 C# 上也返回相同的值,但我的监控程序显示不同的值。会不会是我的主板之类的东西?
  • VARIANT 是一个包含vt 类型标志字段和一个联合的结构。在访问联合字段之前,您应该检查 vt 是否设置为相应的类型,在这种情况下为 VT_I4。使用 V_I4 访问 I4 字段而不进行事先类型检查可能会读取垃圾值。实际上 39 似乎是一个合理的温度值。你有没有运行一些东西来提升它,比如 WinRAR 基准测试?
  • 我理解你的方法,但我没有在我的 C# 代码中使用任何变体结构。我正在使用 Open Hardware Monitor 来检查 CPU 温度,它显示 59-60 C。我在我的 C# 代码上尝试了其他查询(如 CPU 使用情况),它们显示出不同的结果。
  • 我指的是 c++ 代码,尤其是 *pTemperature = V_I4(&amp;v); 行。

标签: c++ wmi


【解决方案1】:

在我看来,这与 VARIANT 无关,因为 Windows 中有这个命令行:

"wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature"

此命令需要管理员角色,然后您将始终看到相同的值。

【讨论】:

  • 感谢您修复我的语法错误。希望与您成为朋友。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-22
  • 2019-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-17
相关资源
最近更新 更多