tags:

views:

2238

answers:

4

I need to gather some system's information for the application I'm developing. The memory available and the CPU load are easy to get using C#. Unfortunately, the CPU temperature it's not that easy. I have tried using WMI but I couldn't get anything using

Win32_TemperatureProbe

or

MSAcpi_ThermalZoneTemperature

Has anybody already dealt with this issue? I'm wondering how monitoring programs, as SiSoftware Sandra, can get that information...

Just in case anybody is interested, here is the code of the class:

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;
    }
}
A: 

Most (if not all) motherboard and CPU vendors never implement the required functionality, so it will never work :(

leppie
It may not work via WMI if the hardware vendors don't provide that info via WMI. On the other hand, if the hardware is homogeneous or otherwise predictable, there should be some method of retrieving the value but it may vary depending on the vendor. Things to check include SNMP and proprietary management tools that may include an API.
steamer25
Most have chipsets and CPUs have their own api calls for this kind of stuff.
ewanm89
Linux kernel has standard interfaces for this stuff which does actually get used. Mostly because they've reversed engineered the hardware call needed and written a driver for it.
ewanm89
ewanm89, that's because the linux kernel use the actual ACPI tables (of whom, most are buggy as hell).
leppie
+3  A: 

I'm pretty sure its manufacturer dependent, since they will be accessed through an I/O port. If you have a specific board you're trying to work with, try looking through the manuals and/or contacting the manufacturer.

If you want to do this for a lot of different boards, I'd recommend contacting someone at something like SiSoftware or be prepared to read a LOT of motherboard manuals.

As another note, not all boards have temperature monitors.

You also might run into problems getting privileged access from the kernel.

samoz
do you know any good open source monitoring tool?
yeyeyerman
+2  A: 

There is a blog post with some C# sample code on how to do it here.

Jon Grant
That still requires that the vendor's driver is exposing it via WMI.
ewanm89
A: 

I know this post i old, but just wanted to add a comment if somebody should be looking at this post and trying to find a soulution for this problem,

You can indeed read the CPU temperature very easy in C# by using a WMI approch.

To get a celcius value i have created a wrapper that converts the value returned by WMI and wraps it into an easy to use object.

Please remember to add a reference to the System.Management.dll in Visual Studio.

Regards
Lasse Rasch
.Net Developer
R-Coding, Software Development

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 Temperatures
        {
            get
            {
                List result = new List();
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(@"root\WMI", "SELECT * FROM MSAcpi_ThermalZoneTemperature");
                foreach (ManagementObject obj in searcher.Get())
                {
                    Double temp = Convert.ToDouble(obj["CurrentTemperature"].ToString());
                    temp = (temp - 2732) / 10.0;
                    result.Add(new Temperature { CurrentValue = temp, InstanceName = obj["InstanceName"].ToString() });
                }
                return result;

            }
        }
    }
}


Update 25.06.2010:

(Just saw that a link was posted to the same kind of soulution above... Anyway. I will leave this piece of code if somebody should want to use it :-) )

Lasse Rasch