Click here to Skip to main content
13,148,510 members (67,172 online)
Click here to Skip to main content
Add your own
alternative version

Stats

19.2K views
2.9K downloads
52 bookmarked
Posted 31 Jul 2016

CPU Temperature & System Information

, 7 Aug 2017
Rate this:
Please Sign up or sign in to vote.
Two classes for easy access to system information using OpenHardWareMonitor and Windows System.Management.

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 it 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<OHMItem> 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 preformatted 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;

// 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;
        }
    }
}

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 changes 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. Using Visual Studio 2015 to run the demo app in debug mode, it's clear that more data is actually available in the OHMonitor class than is coming through when the program runs, so the method for reading the enumerated values could be improved. I have been able to find only limited online documentation for the OHM library so far.

That said, I have found the library to return most relevant information from my homebuilt generic hardware PC which uses a Gigabyte GA-Z170X-UD5 motherboard and Windows 10-64 as well as my older Lenovo Carbon X1 laptop which runs Windows 10-32. Most importantly for a home builder, the CPU temperature is accurate when checked against other sources, such as the CorsairLink utility that came with my liquid CPU cooler.

History

  • 07-30-2016 1st posting ver 1.0.0.9
  • 06-07-2017 2nd posting ver 1.0.2.3
  • 08-07-2017 3rd posting ver 1.0.2.4

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Howard 9448490
United States United States
I am a retired MD who enjoys programming.

You may also be interested in...

Pro

Comments and Discussions

 
GeneralMy vote of 1 Pin
Jordan Wilde31-Aug-17 7:42
memberJordan Wilde31-Aug-17 7:42 
GeneralRe: My vote of 1 Pin
Howard 94484904-Sep-17 11:46
memberHoward 94484904-Sep-17 11:46 
GeneralMy vote of 2 Pin
tbayart25-Jul-17 21:03
membertbayart25-Jul-17 21:03 
GeneralRe: My vote of 2 Pin
Howard 94484907-Aug-17 10:03
memberHoward 94484907-Aug-17 10:03 
GeneralMy vote of 5 Pin
Аslam Iqbal9-Jun-17 22:52
professionalАslam Iqbal9-Jun-17 22:52 
GeneralRe: My vote of 5 Pin
Howard 944849013-Jun-17 6:14
memberHoward 944849013-Jun-17 6:14 
Questionhcwgenericclasses Pin
Member 24433067-Jun-17 12:48
memberMember 24433067-Jun-17 12:48 
AnswerRe: hcwgenericclasses Pin
Howard 944849013-Jun-17 6:13
memberHoward 944849013-Jun-17 6:13 
QuestionThird-party library... Pin
dandy727-Jun-17 5:43
memberdandy727-Jun-17 5:43 
AnswerRe: Third-party library... Pin
Howard 94484907-Jun-17 6:30
memberHoward 94484907-Jun-17 6:30 
GeneralRe: Third-party library... Pin
dandy728-Jun-17 3:53
memberdandy728-Jun-17 3:53 
GeneralRe: Third-party library - Suggestion Pin
Perić Željko11-Jun-17 2:18
professionalPerić Željko11-Jun-17 2:18 
GeneralRe: Third-party library - Suggestion Pin
Howard 94484907-Aug-17 10:14
memberHoward 94484907-Aug-17 10:14 
QuestionCentigrade Temperatures Pin
Howard 94484901-Aug-16 2:30
memberHoward 94484901-Aug-16 2:30 
QuestionFahrenheit vs Celcius Pin
D. Infuehr1-Aug-16 0:44
memberD. Infuehr1-Aug-16 0:44 
AnswerRe: Fahrenheit vs Celcius Pin
dandy727-Jun-17 5:33
memberdandy727-Jun-17 5:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170924.2 | Last Updated 7 Aug 2017
Article Copyright 2016 by Howard 9448490
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid