【问题标题】:How to get cpu temperature? each core separatelycpu温度怎么测?每个核心分别
【发布时间】:2014-06-19 07:51:44
【问题描述】:

我正在使用此代码获取 cpu 温度,但我得到的是“不支持”而不是温度。

public static string getCpuTemperature()
{
    try
    {

        ManagementObjectSearcher searcher =
            new ManagementObjectSearcher("root\\WMI",
            "SELECT * FROM MSAcpi_ThermalZoneTemperature");
        //Win32_TemperatureProbe

        foreach (ManagementObject queryObj in searcher.Get())
        {
            double temp = Convert.ToDouble(queryObj["CurrentTemperature"].ToString());
            double temp_critical = Convert.ToDouble(queryObj["CriticalTripPoint"].ToString());
            double temp_cel = (temp / 10 - 273.15);
            double temp_critical_cel = temp_critical / 10 - 273.15;
            return temp_cel.ToString() + " _ " + temp_critical_cel.ToString();
        }
    }
    catch (ManagementException e)
    {
        //MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
        return e.Message.ToString();
    }
    return "";
}

我已经用谷歌搜索了这个问题,并看到了很多答案,包括: - 主板不支持此功能 - 以管理权限运行 VS 等等……

但它们都不是真的,因为像 OpenHardwareMonitorSpeedFan 这样的程序会显示 cpu 和 gpu 的温度、硬盘温度、cpu 风扇速度和所有其他信息。

我想知道他们是怎么做到的?我怎么会收到“不支持”消息而这些程序却没有。

【问题讨论】:

  • 呃,来自每个核心?所有内核都在同一个 CPU 中,并且通常具有相同的温度。 (除非你有一个多 CPU 系统)
  • 这是非常不正确的,大多数软件都在单核上运行,所以你会得到很大的温差。
  • 我怀疑你提到的软件产品没有使用WMI。
  • 顾名思义,OpenHardwareMonitor 是开源的,你可以看看这里的代码code.google.com/p/open-hardware-monitor/source/browse/trunk/… 比如。
  • @Lithium 为什么不在你的应用程序中引用OpenHardwareMonitorLib.dll

标签: c# asp.net wmi


【解决方案1】:

这不是一个完整的答案,但希望它有所帮助。

仔细阅读https://code.google.com/p/open-hardware-monitor/source/browse/trunk/的代码后,如果不下载并进一步调查,我无法完全理解这段代码。

魔法似乎在这里发生,

public override void Update() {
  base.Update();

  for (int i = 0; i < coreTemperatures.Length; i++) {
    uint eax, edx;
    // if reading is valid
    if (Ring0.RdmsrTx(IA32_THERM_STATUS_MSR, out eax, out edx,
        1UL << cpuid[i][0].Thread) && (eax & 0x80000000) != 0) 
    {
      // get the dist from tjMax from bits 22:16
      float deltaT = ((eax & 0x007F0000) >> 16);
      float tjMax = coreTemperatures[i].Parameters[0].Value;
      float tSlope = coreTemperatures[i].Parameters[1].Value;
      coreTemperatures[i].Value = tjMax - tSlope * deltaT;
    } else {
      coreTemperatures[i].Value = null;
    }
  }

  ...

这段代码从Ring0.RdmsrTx的结果中提取温度数据。

我相信Ring0 是一个环形缓冲区的C 实现,其代码在存储库here 中。这会从 CPU 驱动程序中读取 Model S特定的R寄存器数据。

this question有更多细节。

【讨论】:

  • 文档还说已经有一个 WMI 提供程序可用。 openhardwaremonitor.org/documentation
  • @NoviceProgrammer 这可能是一个实用的解决方案,可以很容易地从 OpenHardwareMonitor 的未来更新中受益。
  • 感谢您的回复,但我正在使用它的 dll (openHardwareMonitorLib.dll) 来完成我的工作。
  • @Lithium,这可能是我会做的,但当然不是你问的。
  • @Jordell 是的,我正在寻找一个可以完成这项工作的示例,但所有链接和指南都将我引导至 openHardwareMonitor。我花了很多时间来做这件事,最后我应该最终从 openHardwareMonitor 复制代码。那我为什么不使用它的dll。我只是不知道我可以在我的项目中使用这个 dll。这就是全部
【解决方案2】:

最简单的方法可能是找到一种工具,该工具可以以机器可读的方式输出您需要的信息,然后处理该输出。 SpeedFan 将温度记录到日志中,您可以从日志中读取最新读数。

我意识到这可能不是一个理想的解决方案,但它是唯一通用的。在 Windows 系统中查询 CPU 温度并非易事。

【讨论】:

  • 那是问题所在。太硬了等等等等等等。
  • 我没有说“太难了”。如果有足够的时间和资源,一切都可以完成。事实是,最好使用久经考验的解决方案来输出 CPU 温度。不是重新发明轮子,可以这么说。当然,这一切都取决于 OP 的需求,但他们没有具体说明解决方案应该有多复杂。这是一个又快又脏的解决方案——我不否认。
  • 我正在开发的应用程序将在大型服务器计算机上运行以监控它们的性能,并向它们的所有者显示有关这些服务器的信息。所以重要的是直接从程序中完成这项工作,而不是阅读其他软件的日志。我知道这并不容易 :) 所以任何想法都将不胜感激!
【解决方案3】:

许多计算机不支持 WMI,运行代码时会显示错误。但我可以通过 openhardwaremonitor 获取 CPU 温度。 这是代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenHardwareMonitor.Hardware;
namespace Get_CPU_Temp5
{
   class Program
   {
       public class UpdateVisitor : IVisitor
       {
           public void VisitComputer(IComputer computer)
           {
               computer.Traverse(this);
           }
           public void VisitHardware(IHardware hardware)
           {
               hardware.Update();
               foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
           }
           public void VisitSensor(ISensor sensor) { }
           public void VisitParameter(IParameter parameter) { }
       }
       static void GetSystemInfo()
       {
           UpdateVisitor updateVisitor = new UpdateVisitor();
           Computer computer = new Computer();
           computer.Open();
           computer.CPUEnabled = true;
           computer.Accept(updateVisitor);
           for (int i = 0; i < computer.Hardware.Length; i++)
           {
               if (computer.Hardware[i].HardwareType == HardwareType.CPU)
               {
                   for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
                   {
                       if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature)
                               Console.WriteLine(computer.Hardware[i].Sensors[j].Name + ":" + computer.Hardware[i].Sensors[j].Value.ToString() + "\r");
                   }
               }
           }
           computer.Close();
       }
       static void Main(string[] args)
       {
           while (true)
           {
               GetSystemInfo();
           }
       }
   }
}

教程可以看这里:http://www.lattepanda.com/topic-f11t3004.html

【讨论】:

    【解决方案4】:

    我可能很晚才回答这个问题,但以防万一将来有人偶然发现这个问题,我就是这样做的:

    public string getCPUTemp()
            {
                UpdateVisitor updateVisitor = new UpdateVisitor();
                Computer computer = new Computer();
                computer.Open();
                computer.CPUEnabled = true;
                computer.Accept(updateVisitor);
                string res = "";
                for (int i = 0; i < computer.Hardware.Length; i++)
    
                {
                    if (computer.Hardware[i].HardwareType == HardwareType.CPU)
    
                    {
                        for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
    
                        {
                            if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature) res = String.Concat(res, (computer.Hardware[i].Sensors[j].Name + ": " + computer.Hardware[i].Sensors[j].Value.ToString() + "ºC" + "\r"));
                            if (computer.Hardware[i].Sensors[j].Value.ToString() == "") { res = ""; return res; }
                        }
    
                    }
                }
    

    它非常适合我(即使它不适用于 GPU 部分)。您只需下载 OpenHardwareMonitor (https://openhardwaremonitor.org/),然后添加对 \openhardwaremonitor\Bin\Debug 文件夹中 OpenHardwareMonitorLib.dll 的引用,然后添加“使用 OpenHardwareMonitor.Hardware;”在顶部。

    希望即使不是 OP,它仍然可以帮助某人!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      相关资源
      最近更新 更多