65.9K
CodeProject 正在变化。 阅读更多。
Home

CPU 温度和系统信息

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.72/5 (37投票s)

2016 年 8 月 1 日

CPOL

5分钟阅读

viewsIcon

94399

downloadIcon

10494

两个类,可方便地使用 OpenHardWareMonitor 和 Windows System.Management 访问系统信息。

引言

由于我使用的是自己组装的 PC,我想要一个简单的应用程序,可以在桌面上不显眼地显示我的 CPU 温度。

背景

这个项目开始于我想编写一个小工具,用开源的 OpenHardwareMonitorLib.dll () 在桌面的角落显示 CPU 温度。 网页在此。该库提供了广泛的硬件信息,包括通过 Windows 管理接口 (WMI) 访问的多个系统温度。然而,我发现有限的文档有点令人困惑,并且在使用 OHM 直接提供的 public 类枚举时效果更好,关键在于在尝试枚举项目和子项之前正确调用 Update 方法。

一旦我让它工作起来,我就创建了一个包装类 OHData,它有一个 public 属性 DataList 和一个 public 方法 Update

由于我无法从 OHM 提取 BIOS 信息(尽管在调试时它是可见的),我还创建了一个小的独立包装类 WMBIOS,它使用 System.Management 获取相关信息(也请将此引用添加到您的项目中)。

以下是演示应用程序的示例

温度窗口

系统信息弹出窗口

Using the Code

要使用该代码,请在您的项目中包含 OpenHardwareMonitorLib.dll 的副本,并添加对它的引用。然后创建一个 OHdata 的本地实例,例如 OHData od = new OHData(),调用 update 方法,并在 List<OHMItem> 对象中获取结果,每个 OHItem 由传感器类型、传感器名称和读数(均为 string)组成。OHMItem 类结构是 OHData 的一个 public 成员。检索列表中的 OHItems 已经预格式化为大多数类型,例如电压、温度和风扇速度,可直接在 ListView 中使用。如果您只想使用 CPU 温度,可以在列表中搜索 Type = "Temperature"Name = "CPU"

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Reflection;
using System.IO;
using System.Management;
using OpenHardwareMonitor;
using OpenHardwareMonitor.Collections;
using OpenHardwareMonitor.Hardware;

// REQUIRES OpenHardwareMonitorLib.dll added to project

namespace <your project namespace goes here>
{
    static class Program
    {
        /// 
        /// The main entry point for the application.
        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
            }
    
    /// Wrapper For OpenHarwareMonitor.dll
    /// 
    public class OHData
    {
        // DATA ACCESSOR
        public List<ohmitem> DataList
        {
            get
            {
                return ReportItems;
            }
            set
            {

            }

        }
        // UPDATE METHOD
        public void Update()
        {
            UpdateOHM();
        }

        // for report compilation
        public class OHMitem
        {
            public OHMitem()
            {
            }
            public string name
            {
                get
                {
                    return Name;
                }
                set
                {
                    Name = value;
                }
            }
            public string type
            {
                get
                {
                    return OHMType;
                }
                set
                {
                    OHMType = value;
                }
            }
            public string reading
            {
                get
                {
                    return OHMValue;
                }
                set
                {
                    OHMValue = value;
                }
            }

            private string Name = String.Empty;
            private string OHMType = String.Empty;
            private string OHMValue = String.Empty;

        }
        // for report compilation
        private List<ohmitem> ReportItems = new List<ohmitem>();
        // ADDS ITEMS TO REPORT
        private void AddReportItem(string ARIName, string ARIType, string ARIValue)
        {
            // int readingwidth = 26;
            if (ARIType == "Data")
            {
                return; // ignore data items
            }
            OHMitem ARItem = new OHMitem();
            ARItem.name = ARIName;
            ARItem.type = ARIType + ": ";
            ARItem.reading = ARIValue;
            if (ARIType == "GpuAti")
            {
                ARItem.type = "Graphics Card";
            }

            if (ARIType == "Temperature")
            {
                try
                {
                    double temp = Convert.ToDouble(ARIValue);
                    ARItem.reading = ((((9.0 / 5.0) * temp) + 32).ToString("000.0") + " F");
                }
                catch
                {
                    
                    return;
                }
            }
            if (ARIType == "Clock")
            {
                try
                {
                    double temp = Convert.ToDouble(ARIValue);
                    if (temp < 1000)
                    {
                        ARItem.reading = (temp.ToString("F1") + " MHZ");
                    }
                    else
                    {
                        temp = temp / 1000;
                        ARItem.reading = (temp.ToString("F1") + " GHZ");
                    }
                }
                catch
                {
                    return;
                }

            }
            if (ARIType == "Control" || ARIType == "Load")
            {
                try
                {
                    double temp = Convert.ToDouble(ARIValue);
                    ARItem.name = ARIName;
                    ARItem.reading = (temp.ToString("F0") + " %");
                }
                catch
                {
                    return;
                }
            }
            if (ARIType == "Voltage")
            {
                try
                {
                    double temp = Convert.ToDouble(ARIValue);
                    ARItem.name = ARIName;
                    ARItem.reading = (temp.ToString("F1") + " V");
                }
                catch
                {
                    return;
                }
            }
            // 07-28-2016 Added This item
            if (ARIType == "Fan")
            {
                try
                {
                    double rpm = Convert.ToDouble(ARIValue);
                    ARItem.name = ARIName;
                    ARItem.reading = (rpm.ToString("F0") + " RPM");
                }
                catch
                {
                    return;
                }
            }

            ReportItems.Add(ARItem);
        }
        // LOCAL INSTANCE OHM
        private OpenHardwareMonitor.Hardware.Computer computerHardware = 
        new OpenHardwareMonitor.Hardware.Computer();
        // UPDATE OHM DATA
        private void UpdateOHM()
        {
            
            string s = String.Empty;
            string name = string.Empty;
            string type = string.Empty;
            string value = string.Empty;
            int x, y, z, n;
            int hardwareCount;
            int subcount;
            int sensorcount;
            ReportItems.Clear();
            computerHardware.MainboardEnabled = true;
            computerHardware.FanControllerEnabled = true;
            computerHardware.CPUEnabled = true;
            computerHardware.GPUEnabled = true;
            computerHardware.RAMEnabled = true;
            computerHardware.HDDEnabled = true;
            computerHardware.Open();
            hardwareCount = computerHardware.Hardware.Count();
            for (x = 0; x < hardwareCount; x++)
            {
                name = computerHardware.Hardware[x].Name;
                type = computerHardware.Hardware[x].HardwareType.ToString();
                value = ""; // no value for non-sensors;
                AddReportItem(name, type, value);

                subcount = computerHardware.Hardware[x].SubHardware.Count();

                // ADDED 07-28-2016
                // NEED Update to view Subhardware
                for (y = 0; y < subcount; y++)
                {
                    computerHardware.Hardware[x].SubHardware[y].Update();
                }
                //
               
                if (subcount > 0)
                {
                    for (y = 0; y < subcount; y++)
                    {
                        sensorcount = computerHardware.Hardware[x].
                        SubHardware[y].Sensors.Count();
                        name = computerHardware.Hardware[x].SubHardware[y].Name;
                        type = computerHardware.Hardware[x].SubHardware[y].
                        HardwareType.ToString();
                        value = "";
                        AddReportItem(name, type, value);

                        if (sensorcount > 0)
                        {
                            
                            for (z = 0; z < sensorcount; z++)
                            {
                                
                                name = computerHardware.Hardware[x].
                                SubHardware[y].Sensors[z].Name;
                                type = computerHardware.Hardware[x].
                                SubHardware[y].Sensors[z].SensorType.ToString();
                                value = computerHardware.Hardware[x].
                                SubHardware[y].Sensors[z].Value.ToString();
                                AddReportItem(name, type, value);
                                
                            }
                        }
                    }
                }
                sensorcount = computerHardware.Hardware[x].Sensors.Count();
                
                if (sensorcount > 0)
                {
                    for (z = 0; z < sensorcount; z++)
                    {
                        name = computerHardware.Hardware[x].Sensors[z].Name;
                        type = computerHardware.Hardware[x].Sensors[z].SensorType.ToString();
                        value = computerHardware.Hardware[x].Sensors[z].Value.ToString();
                        AddReportItem(name, type, value);
                        
                    }
                }
            }
           computerHardware.Close();
        }
    }
    /// <summary>
    /// Wrapper for BIOS Information from Win_32BIOS WMI
    /// </summary>
    public class WMIBIOS
    {
        public string Name
        {
            get
            {
                return name;
            }
           
        }
        public string Manufacturer
        {
            get
            {
                return manufacturer;
            }
        }
        public string Date
        {
            get
            {
                return FormatDate(date);
            }

        }
        public string Version
        {
            get
            {
                return version;
            }

        }
        public void Update()
        {
            update();
        }
        private string name = String.Empty;
        private string manufacturer = String.Empty;
        private string date = String.Empty;
        private string version = String.Empty;
        // Get BIOS Data using WMI
        private void update()
        {
            
            
            ManagementObjectSearcher searcher = 
            new ManagementObjectSearcher(@"\\.\root\cimv2", "SELECT * FROM Win32_BIOS");
            ManagementObjectCollection collection = searcher.Get();
            foreach (ManagementObject o in collection)
            {
                try
                {
                    name = Convert.ToString(o.GetPropertyValue("Name"));
                }
                catch
                {
                    name = String.Empty;
                }
                try
                {
                    date = Convert.ToString(o.GetPropertyValue("ReleaseDate"));
                }
                catch
                {
                    date = String.Empty;
                }
                try
                {
                    manufacturer = Convert.ToString(o.GetPropertyValue("Manufacturer"));
                }
                catch
                {
                    manufacturer = String.Empty;
                }
                try
                {
                    version = Convert.ToString(o.GetPropertyValue("SMBIOSBIOSVersion"));
                }
                catch
                {
                    version = String.Empty;
                }
            }
            searcher.Dispose();
            return;
        }
        // FORMAT DATE FROM WIN_32 BIOS INTO USABLE FORM
        private string FormatDate(string rawdata)
        {
            string result = String.Empty;
            string year = String.Empty;
            string month = String.Empty;
            string day = String.Empty;
            try
            {
                year = rawdata.Substring(0, 4);
                month = rawdata.Substring(4, 2);
                day = rawdata.Substring(6, 2);
            }
            catch
            {
                return result;
            }
            result = month + "-" + day + "-" + year;
            return result;
        }
    }
}

关注点

通过这两个类,大多数有用的系统信息都可用。请注意,OHM 返回的传感器和结果取决于底层硬件。例如,在我自己组装的技嘉主板 PC 上显示的系统板电压在我的联想 Carbon X1 上就显示不出来。

Temperature.exe”示例应用程序演示了如何使用它们。它在屏幕右下角打开一个小的半透明窗口,显示 CPU 温度,每 60 秒更新一次。右键单击该窗口会打开一个上下文菜单,其中包含退出、显示系统信息和更改更新间隔的选项。请注意,我必须为 Windows 8 和 10 添加自定义清单,以获得更高的访问权限,这可能是因为 OpenHardwareMonitor 直接与硬件交互。在 Windows 7 中不需要这样做。这在解决方案资源管理器中显示为“app.manifest”。可以在项目 -> 属性的应用程序窗口中添加自定义清单。在版本 1.0.2.3 中,我添加了一个备份方法来计算可用内存(空闲和已用),以防 OHMonitor 数据中缺少此信息,并添加了更多来自其他来源的关于 BIOS 的信息。仍然有一些 OHMonitor 子项的预期数据为空。如果有人找到提取丢失字段的解决方案,请告诉我。使用 Visual Studio 2015 在调试模式下运行演示应用程序,可以清楚地看到 OHMonitor 类中实际上有更多数据可用,而不是在程序运行时通过的,因此读取枚举值的方法可以改进。到目前为止,我只能找到 OHM 库有限的在线文档。

话虽如此,我发现该库能够从我使用技嘉 GA-Z170X-UD5 主板和 Windows 10-64 的自己组装的通用硬件 PC 以及运行 Windows 10-32 的旧联想 Carbon X1 笔记本电脑中返回大多数相关信息。最重要的是,对于自己组装的硬件,CPU 温度与其他来源(例如与我的液体 CPU 散热器一起提供的 CorsairLink 实用程序)进行检查时是准确的。

更新 2017-11-07  遵循一个建议,我尝试在读取其值后保持 OHM ComputerHardware 实例打开,而不是在使用后调用 .Close() 方法。  这似乎会遗漏硬件枚举中的一些子项,因此您每次查询时都必须打开和关闭实例。  我在尝试使用 OHM 提供的 WMI 接口方面没有取得进一步的成功,因为几乎没有文档。  示例应用程序现在会平均报告的 CPU 温度以获得其显示的温度。  总的来说,它报告的信息现在与 OHM 本身的应用程序以及来自 BIOS 或第三方系统信息实用程序(如 CorsairLink)的数据非常接近。  在此版本中,我添加到列表中的其他外部项是当前显示分辨率和 Windows 10 版本号。

更新 2019-11-24  遵循会员 14615649 的建议,添加了选项功能和温度日志记录。黄色和红色警报温度阈值可以自定义,小显示窗口的透明度也可以自定义。该程序还将 CPU 温度保存到日志中,并使用 net DataVisualization API 以图表形式显示。要放大图表的某个部分,请单击并拖动以在其上选择感兴趣的区域。将鼠标悬停在图表上的数据点上会显示其实际温度读数。

历史

  • 2016-07-30 首次发布 ver 1.0.0.9
  • 2017-06-07 第二次发布 ver 1.0.2.3
  • 2017-08-07 第三次发布 ver 1.0.2.4
  • 2017-11-07 第四次发布 ver 1.0.2.8
  • 2019-11-24 第五次发布 ver 1.0.4.0
© . All rights reserved.