CPU Temperature & System Information

0
88

Introduction

Since I use a homebuilt PC, I wanted a simple application to display  my CPU temperature unobstrusively on my desktop.
 

Background

This project started when I wanted to write a small utility to display the CPU temperature in a corner of the desktop using the open source OpenHardwareMonitorLib.dll ().  Web Page Here This library provides extensive hardware information, including multiple system temperatures accessible through a Windows Management Interface (WMI).  However, I found the limited documentation available somewhat confusing and had better luck using the public class enumerations provided by OHM directly, the key being to call the Update methods correctly for items and subitems before attempting to enumerate them.

Once I got it working, I created a wrapper class, OHData which has one public property, DataList and one public method, Update.

Since I was not able to extract BIOS information from OHM (even though its is visible when debugging),   I also created a small separate wrapper class,  WMBIOS, which gets the relevant information using System.Management (add this reference to your project as well).

Here are samples from the demo application:

The temperature window:

The system information popup window:

Using the code

To use the code, include a copy of OpenHardwareMonitorLib.dll in your project, add a reference to it. Then create a local instance of OHdata, for example OHData od = new OHData(),  call the update method and get the results in a List object, each OHItem consisting of a Sensor Type, Sensor Name, and reading (all strings).  The OHMItem class structure is a public member of OHData.  OHItems in the retrieved list are preformated for most types, such as voltages, temperatures, and fan speeds, ready to use in a ListView.   To get just the CPU temperature, you can search the List for Type = “Temperature” and Name = “CPU” if you just want to use that.

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; namespace <your project namespace goes here> { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } } public class OHData { public List DataList { get { return ReportItems; } set { } } public void Update() { UpdateOHM(); } 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; } private List ReportItems = new List(); private void AddReportItem(string ARIName, string ARIType, string ARIValue) { if (ARIType == "Data") { return; } 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; } } if (ARIType == "Fan") { try { double rpm = Convert.ToDouble(ARIValue); ARItem.name = ARIName; ARItem.reading = (rpm.ToString("F0") + " RPM"); } catch { return; } } ReportItems.Add(ARItem); } private OpenHardwareMonitor.Hardware.Computer computerHardware = new OpenHardwareMonitor.Hardware.Computer(); 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 = ""; AddReportItem(name, type, value); subcount = computerHardware.Hardware[x].SubHardware.Count(); 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(); } } 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; 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; } 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; } } } </ohmitem></ohmitem></ohmitem>

Points of Interest

Between these two classes most useful system information is available. Note that OHM returns different sensors and results depending on the underlying hadware. For example, system board voltages that show up on my home built gigabyte motherboard PC don’t show up in the list on my Lenovo Carbon X1.  

The “Temperature.exe” sample application shows how to use them. It opens a small partially transparent window in the right lower corner of the screen with the CPU temperature display, updating every 60 seconds. Right-clicking the window opens a context menu with options to quit, display system information, and change the update interval. Note that I had to add a custom manifest to the project for Windows 8 and 10 with a higher access privilege, probably because OpenHardwareMonitor interacts with the hardware directly.  This wasn’t necessary in Windows 7. This shows up as “app.manifest” in Solution Explorer.  A custom manifest can be added in the Application Window of Project->Properties.  With Version 1.0.2.3, I added a backup method for calculating available Free and Used Memory if this is missing from the OHMonitor data, and more information from other sources regarding the BIOS.  There are still some OHMonitor subitems where the expected data remains blank.  If someone finds a solution to extracting the missing fields, please let me know.

History

07-30-2016 1st Posting ver 1.0.0.9

06-07-2017 2nd Posting ver 1.0.2.3

LEAVE A REPLY