.net 如何获取CPU温度?

um6iljoc  于 2023-06-25  发布在  .NET
关注(0)|答案(9)|浏览(252)

我需要为我正在开发的应用程序收集一些系统信息。可用内存和CPU负载很容易使用C#获得。不幸的是,CPU的温度就没那么容易了.我已经尝试使用WMI,但我不能得到任何使用

Win32_TemperatureProbe

MSAcpi_ThermalZoneTemperature

我该怎么做?我想知道如何监控程序,作为SiSoftware桑德拉,可以得到这些信息...
下面是类的代码:

public class SystemInformation
{
    private System.Diagnostics.PerformanceCounter m_memoryCounter;
    private System.Diagnostics.PerformanceCounter m_CPUCounter;

    public SystemInformation()
    {
        m_memoryCounter = new System.Diagnostics.PerformanceCounter();
        m_memoryCounter.CategoryName = "Memory";
        m_memoryCounter.CounterName = "Available MBytes";

        m_CPUCounter = new System.Diagnostics.PerformanceCounter();
        m_CPUCounter.CategoryName = "Processor";
        m_CPUCounter.CounterName = "% Processor Time";
        m_CPUCounter.InstanceName = "_Total";
    }

    public float GetAvailableMemory()
    {
        return m_memoryCounter.NextValue();
    }

    public float GetCPULoad()
    {
        return m_CPUCounter.NextValue();
    }

    public float GetCPUTemperature()
    {
        //...
        return 0;
    }
}
v2g6jxz6

v2g6jxz61#

对于其他可能来到这里的人,也许可以看看:http://openhardwaremonitor.org/
按照这个链接,一开始你可能会想,“嘿,这是一个 * 应用程序 *,这就是为什么它被删除。问题是如何从C#代码中做到这一点,而不是找到一个可以告诉我温度的应用程序......”这就是它表明你不愿意投入足够的时间来阅读“开放硬件监视器”也是什么。
它们还包括数据接口。以下是描述:

数据接口Open Hardware Monitor将所有传感器数据发布到WMI(Windows Management Instrumentation)。这也允许其他应用读取和使用传感器信息。可以在here (click)找到接口的初步文档。

当您下载它时,它包含OpenHardwareMonitor.exe应用程序,您并没有在寻找该应用程序。它还包含OpenHardwareMonitorLib.dll,您正在寻找的是这个。
如果不是100%的话,它主要是WinRing0 API的 Package 器,如果你喜欢的话,你可以选择 Package 自己。
我已经在一个C#应用程序中尝试过了这个方法,它很有效。虽然还在测试阶段,但看起来还算稳定。它也是开源的,所以它可能是一个很好的起点。

vaqhlq81

vaqhlq812#

通过使用WMI方法,您确实可以在C#中非常容易地读取CPU温度。
为了获得摄氏温度,我创建了一个 Package 器,该 Package 器转换WMI返回的值,并将其 Package 成易于使用的对象。
请记住在Visual Studio中添加对System.Management.dll的引用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;

namespace RCoding.Common.Diagnostics.SystemInfo
{
    public class Temperature
    {
        public double CurrentValue { get; set; }
        public string InstanceName { get; set; }
        public static List<Temperature> Temperatures
        {
            get
            {
                List<Temperature> result = new List<Temperature>();
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"root\WMI", "SELECT * FROM MSAcpi_ThermalZoneTemperature");
                foreach (ManagementObject obj in searcher.Get())
                {
                    Double temperature = Convert.ToDouble(obj["CurrentTemperature"].ToString());
                    temperature = (temperature - 2732) / 10.0;
                    result.Add(new Temperature { CurrentValue = temperature, InstanceName = obj["InstanceName"].ToString() });
                }
                return result;
            }
        }
    }
}
b1uwtaje

b1uwtaje3#

我很确定它依赖于制造商,因为它们将通过I/O端口访问。如果你有一个特定的板,你试图工作,尝试查看手册和/或联系制造商。
如果你想为很多不同的主板做这件事,我建议你联系像SiSoftware这样的人,或者准备阅读大量的主板手册。
另一个注意事项是,并非所有主板都有温度监视器。
您还可能在从内核获取特权访问时遇到问题。

mefy6pfw

mefy6pfw4#

你可以给予Open Hardware Monitor,尽管它不支持最新的处理器。

internal sealed class CpuTemperatureReader : IDisposable
{
    private readonly Computer _computer;

    public CpuTemperatureReader()
    {
        _computer = new Computer { CPUEnabled = true };
        _computer.Open();
    }

    public IReadOnlyDictionary<string, float> GetTemperaturesInCelsius()
    {
        var coreAndTemperature = new Dictionary<string, float>();

        foreach (var hardware in _computer.Hardware)
        {
            hardware.Update(); //use hardware.Name to get CPU model
            foreach (var sensor in hardware.Sensors)
            {
                if (sensor.SensorType == SensorType.Temperature && sensor.Value.HasValue)
                    coreAndTemperature.Add(sensor.Name, sensor.Value.Value);
            }
        }

        return coreAndTemperature;
    }

    public void Dispose()
    {
        try
        {
            _computer.Close();
        }
        catch (Exception)
        {
            //ignore closing errors
        }
    }
}

official source下载ZIP文件,提取并添加对项目中文件 * OpenHardwareMonitorLib.dll * 的引用。

zvms9eto

zvms9eto5#

我将CPU部分从Open Hardware Monitor提取到一个单独的库中,暴露了通常隐藏在OHM中的传感器和成员。
它还包括许多更新(例如对RyzenXeon的支持),因为自2015年以来,Open Hardware Monitor(OHM)就没有接受过pull请求。
https://www.nuget.org/packages/HardwareProviders.CPU.Standard/

niwlg2el

niwlg2el6#

这取决于您的计算机是否支持WMI。我的计算机也无法运行此WMI演示。
但是我成功地通过 Open Hardware Monitor 获得了CPU温度。在Visual Studio中添加Openhardwaremonitor引用。这样更容易试试这个:

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();
           }
       }
   }
}

您需要以管理员身份运行此演示。
您可以在 Using Open Hardware Monitor to get CPU temperature in C# and make a fan cooling system 中查看教程。

42fyovps

42fyovps7#

提到的WMI类在最新版本的Windows 10中不适用。
在我的戴尔笔记本电脑上,我可以通过PowerShell获得以摄氏度为单位的CPU温度:

$data = Get-WMIObject -Query "SELECT * FROM Win32_PerfFormattedData_Counters_ThermalZoneInformation" -Namespace "root/CIMV2"
@($data)[0].HighPrecisionTemperature
92vpleto

92vpleto8#

它可以通过WMI在您的代码中完成。我发现了一个来自Microsoft的工具(WMI Code Creator v1.0),它可以为它创建代码。
WMI代码创建器工具允许您生成VBScript、C#和VB .NET代码,这些代码使用WMI来完成管理任务,例如查询管理数据、执行WMI类中的方法或使用WMI接收事件通知。

pkmbmrz7

pkmbmrz79#

由于CPU/芯片组合越来越多,因此需要一个聪明的矩阵来检查所有可能的组合,以识别温度数据。你真的需要一个外部DLL,如“LibreHardwareMonitorLib.dll”来解决这个问题。项目文件可用here
基于此,PowerShell解决方案可能看起来像这样:

#Requires -RunAsAdministrator

cls
$dll = "LibreHardwareMonitorLib.dll"

Unblock-File -LiteralPath $dll
Add-Type -LiteralPath $dll
$monitor = [LibreHardwareMonitor.Hardware.Computer]::new()
$monitor.IsCPUEnabled = $true

$monitor.Open()
[int]$temp = foreach ($sensor in $monitor.Hardware.Sensors) {
    if ($sensor.SensorType -eq 'Temperature' -and $sensor.Name -eq 'Core Average'){
        $sensor.Value
        break
    }
}
$monitor.Close()
write-host "CPU-Package Temperature = $temp°C" -f y

相关问题