Search Unity

Using System.Management (ManagementBaseObject) to get CPU usage etc.

Discussion in 'Scripting' started by Engfii, Feb 14, 2016.

  1. Engfii

    Engfii

    Joined:
    Feb 14, 2016
    Posts:
    2
    Hey guys,

    hopefully someone can help me with my problem. I already searched on google and here in the forum, but I can't find help respectively I can't find a solution which works for me...

    Actually I'm trying to read out CPU usage, GPU usage, RAM usage etc. via the System.Management.dll .
    I already included this in my asset folder (the right one for unity/mono) and of course there is a using System.Management; at the top of my c# scripts. Also I switched API level from .NET 2.0 subset to .NET 2.0 ... and of course I have an assembly reference in my c# solution!

    Here is a bit of the code where I'm trying to access the CPU usage:

    Code (csharp):
    1. ManagementObject objCPU = new ManagementObject("Win32_Processor");
    2. kMeasurement.un_CPU_CurrentClockSpeed = (uint)(objCPU["CurrentClockSpeed"]);
    3. kMeasurement.un_CPU_CurrentVoltage = (uint)(objCPU["CurrentVoltage"]);
    4. kMeasurement.un_CPU_LoadPercentage = (uint)(objCPU["LoadPercentage"]);
    5. kMeasurement.un_CPU_ThreadCount = (uint)(objCPU["ThreadCount"]);
    6. objCPU.Dispose();
    (In this case kMeasurement is only a class which stores a lot of uint!)

    Everytime I click on play in the editor the programm starts and anything is just fine, when the programm gets to this point it throws an error in the console but continues. The error:

    InvalidProgramException: Invalid IL code in System.Management.ManagementBaseObject:get_Item (string): IL_0000: ret

    (wrapper remoting-invoke-with-check) System.Management.ManagementBaseObject:get_Item (string)
    LevelScript.gatherInformation (Single fFPS) (at Assets/_Scripts/LevelScript.cs:136)
    LevelScript.Update () (at Assets/_Scripts/LevelScript.cs:60)

    I read a lot about System.Management in "cooperation" with Mono and Unity3D, some people said it works, other said it doesn't. I'm really confused and I don't know how to go on... I need to read out this data for my bachelor thesis and I hope you guys can help me to solve this problem.

    Maybe someone knows an alternative way to gather this information in Unity?! I'm grateful for any kind of help :)

    Thank you and greetings from North Rhine-Westphalia :)
     
  2. notoriousnary

    notoriousnary

    Joined:
    Jul 16, 2015
    Posts:
    9
    Managed to do exactly what your looking for by implementing Open Hardware Monitors code (its open source) it works fantastic and is even compatible with Linux using Mono. It even has support for running a simple webserver page http://openhardwaremonitor.org/downloads/
     
  3. Engfii

    Engfii

    Joined:
    Feb 14, 2016
    Posts:
    2
    Hey notoriousnary,

    thank you for your reply. I was so focused on how to get System.Management.dll to run, that I totally failed to see the way via the Open Hardware Monitor. The idea sounds great but by implementation in my code I get this error:

    ObjectDisposedException: The object was used after being disposed.
    System.Runtime.InteropServices.SafeHandle.Close () (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs:83)
    System.Runtime.InteropServices.SafeHandle.Dispose (Boolean disposing) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs:180)
    System.Runtime.InteropServices.SafeHandle.Dispose () (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.InteropServices/SafeHandle.cs:162)
    OpenHardwareMonitor.Hardware.KernelDriver.Open ()
    OpenHardwareMonitor.Hardware.Ring0.Open ()
    OpenHardwareMonitor.Hardware.Computer.Open ()
    LevelScript.Start () (at Assets/_Scripts/LevelScript.cs:50)

    I thought maybe you could help me out one more time, because obviously you know how to get this to work!

    Here is the could were I'm trying to get the informations:
    Code (csharp):
    1.  
    2. private Computer kSubject;
    3.  
    4. public void Start()
    5. {
    6.     kSubject = new Computer();
    7.     kSubject.CPUEnabled = true;
    8.     kSubject.GPUEnabled = true;
    9.     kSubject.RAMEnabled = true;
    10.     kSubject.Open();
    11. }
    12.  
    13. [...]
    14.  
    15. public void gatherInformation()
    16. {
    17.     foreach(var vSubjectHardware in kSubject.Hardware)
    18.         {
    19.             if(vSubjectHardware.HardwareType == HardwareType.CPU)
    20.             {
    21.                 vSubjectHardware.Update();
    22.                 foreach(IHardware iSubjectHardware in vSubjectHardware.SubHardware)
    23.                 {
    24.                     iSubjectHardware.Update();
    25.                 }
    26.                 foreach (var vSubjectHardwareSensor in vSubjectHardware.Sensors)
    27.                 {
    28.                     if(vSubjectHardwareSensor.SensorType == SensorType.Clock)
    29.                     {
    30.                         Debug.Log(vSubjectHardwareSensor.Name + ": " + (vSubjectHardwareSensor.Value.HasValue ? vSubjectHardwareSensor.Value.ToString() : "no valide value"));
    31.                     }
    32.                 }
    33.             }
    34.         }
    35. }
    Thank you for your help!