Get the Cpu usage of each process from wmi - c#

I found many sources to get the cpu usage of each process. in general there are many ways to get the cpu usage of process .
percentprocessortime from win32_perfformatteddata_perfproc_process
performancecounter class in system.diagnostics
by manual calculation
Process class (by process.getcurrentprocess().totalprocessortime;)
as said in here.
FirstWay:
For the remote process monitoring(my scenario is remote monitoring), the percentprocessortime always shows value 0 to 100+. this 100+ happens because of multiple processors in a system. it can be calculated by using percentprocessortime/ processorcount.
Question in firstway:
i can read the percentprocessortime in wmi explorer, it shows all the values are 0 or 100 only not other than this value. is this value is correct? or is it useful for monitoring the value?
Second Way:
for PerformanceCounter class monitoring, it can be done for local only. so i cannot use this. is it possible to use this for remote?
Third Way:
(biggest confusion happening here in terms of which formula to use.) this calculation is made either by a PerformanceCounter class or win32_process class from wmi. some says to calculate the performance counter by using the follwing
consider single CPU and
(processor\%processor time) = 10%
(processor\%user time) = 8%
(processor\% privilege time) = 2%
(process\% processor time\your application) = 80%
You application is using 80% of the (processor\% user time) which is (8*.8)=6.4% of the CPU.
for more refer here.
by calculating the usermodetime and kernelmodetime from win32_process by using the following formulae
DateTime firstSample, secondSample;
firstSample = DateTime.Now;
queryObj.Get();
//get cpu usage
ulong u_oldCPU = (ulong)queryObj.Properties["UserModeTime"].Value
+(ulong)queryObj.Properties["KernelModeTime"].Value;
//sleep to create interval
System.Threading.Thread.Sleep(1000);
//refresh object
secondSample = DateTime.Now;
queryObj.Get();
//get new usage
ulong u_newCPU = (ulong)queryObj.Properties["UserModeTime"].Value
+ (ulong)queryObj.Properties["KernelModeTime"].Value;
decimal msPassed = Convert.ToDecimal(
(secondSample - firstSample).TotalMilliseconds);
//formula to get CPU ussage
if (u_newCPU > u_oldCPU)
PercentProcessorTime = (decimal)((u_newCPU - u_oldCPU) /
(msPassed * 100 * Environment.ProcessorCount));
Console.WriteLine("Process name " + queryObj.Properties["name"].value);
Console.WriteLine("processor time " + PercentProcessorTime);
the above code results output in 85.999 and sometimes 135.89888. i was so confused which way can i calculate the cpu usage of process.
Note:
Its a duplicate. I cannot come to the conclusion from the existing sources. and i was confused. so only i asked a question.

You can use WMI to query this. I think you are looking for Win32_PerfFormattedData_PerfProc_Process class.
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class MyWMIQuery
{
public static void Main()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_PerfFormattedData_PerfProc_Process");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Name: {0}", queryObj["Name"]);
Console.WriteLine("PercentProcessorTime: {0}", queryObj["PercentProcessorTime"]);
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
}
}
Output:-

Related

Getting Current Reading of CIM_Tachometer in order to Get Fan Current Speed

I am working on a project which supposed to include computer's fans status. Most of the properties I need can be acquired from the Win32_Fan class. Sadly, I couldn't find a way to use this class for getting the current reading of the fan speed. In the Win32_Fan MSDN page it is mentioned in the "DesiredSpeed" property that the current speed is determined by a sensor named CIM_Tachometer:
DesiredSpeed
Data type: uint64
Access type: Read-only
Qualifiers: Units ("revolutions per minute")
Currently requested fan speed, defined in revolutions per minute, when
a variable speed fan is supported (VariableSpeed is TRUE). The current
speed is determined by a sensor (CIM_Tachometer) that is associated
with the fan using the CIM_AssociatedSensor relationship.
This property is inherited from CIM_Fan.
For more information about using uint64 values in scripts, see
Scripting in WMI.
After I saw that, I searched for this Tachometer CIM sensor and found the following code snippet (which was taken from http://wutils.com/wmi/root/cimv2/cim_tachometer/cs-samples.html):
//Project -> Add reference -> System.Management
//using System.Management;
//set the class name and namespace
string NamespacePath = "\\\\.\\ROOT\\cimv2";
string ClassName = "CIM_Tachometer";
//Create ManagementClass
ManagementClass oClass = new ManagementClass(NamespacePath + ":" + ClassName);
//Get all instances of the class and enumerate them
foreach (ManagementObject oObject in oClass.GetInstances())
{
//access a property of the Management object
Console.WriteLine("Accuracy : {0}", oObject["Accuracy"]);
}
And so I tried implementing it in my code:
public static String[] GetFanInfo()
{
ManagementClass cSpeed = new ManagementClass
("\\\\.\\ROOT\\cimv2:CIM_Tachometer"); //Create ManagementClass for the current speed property
ManagementObjectSearcher temp = new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSAcpi_ThermalZoneTemperature"); //Create management object searcher for the temperature property
ManagementObjectSearcher mos = new ManagementObjectSearcher
("SELECT * FROM Win32_Fan"); //Create a management object searcher for the other properties
string[] Id = new string[8]; //Preparig a string array in which the results will be returned
Id[0] = "Fan"; //First value is the category name
foreach (ManagementObject mo in mos.Get())
{
Id[1] = mo["Name"].ToString(); //Name of the component
Id[2] = mo["Status"].ToString(); //Component's status
long vel = Convert.ToInt64(mo["DesiredSpeed"]); //Desired speed of the component
Id[4] = Convert.ToString(vel);
bool s = Convert.ToBoolean(mo["variableSpeed"]); //Wheater or not variable speed are supported
Id[5] = s.ToString();
break;
}
foreach (ManagementObject obj in temp.Get())
{
Double temperature = Convert.ToDouble(obj["CurrentTemperature"].ToString()); //Fetching the temperature
Id[3] = Convert.ToString((temperature - 2732) / 10.0) + " C";
}
foreach (ManagementObject sObject in cSpeed.GetInstances()) //Get all instances of the class and enumerate them
{
Id[7] = sObject["CurrentReading"].ToString(); //Getting the current reading
}
return Id;
}
To my surprise, it seems that the whole section of the current reading is skipped during runtime. occur anyway!
My question is, why is this certain part skipped? Is the Tachometer a sensor which cannot be used? is it disabled for some reason?
Thanks ahead.
P.S.
I'm writing the program in Microsoft Visual Studio 2015 using winforms for the user interface.

C# SQL insert into Netezza. Netezza not sending return, c# code timing out

I'd really like some advice on this as I have been running into this issue quite a bit now. I have a couple applications, both big and small where I need to do some work with Netezza. Unfortunately, it seems a common issue with .net and Netezza, is Netezza takes a sql command, executes it (I have confirmed it in the log), but periodically does not send a return back, and my OLEDB connection in my C# app just sits there and times out. In the Netezza log I can also see that my session just sits there open, because my app is still waiting for NZ to send something back. This seems to happen only with a connection that executes more than 1 command.
Anyways, below is some code and I want some advice on how to mitigate this issue. I currently but in a retry count, but I'd really like something maybe more fail-safe. Does anyone have any advice on how to deal with an issue like this where you may not receive a return?
This particular loop is about 135 record updates, and only takes 1 minute normally. The lack of return isn't on any specific record. It's completely random and happens in other applications as well.
Any advice would be appreciated! Thank you!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.OleDb;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.Security.Cryptography;
using System.IO;
namespace RemoveVoidedInvoices
{
class UpdateNetezza
{
public bool NetezzaWorkFailure = false;
private void NetezzaWorkFailed()
{
NetezzaWorkFailure = true;
}
public void updateCounts(List<RecordCounts> recordCounts)
{
string connString = string.Format("Provider=NZOLEDB;Data Source={0};Initial Catalog=EBIDW;User ID=MYUSERNAME;Password={1}", Environment, passWord);
OleDbConnection netezzaConn = null;
//Due to timeout issues I am making a quick timespan entry so that I can keep track in the log of how long each day the bulk update took
DateTime Prequery = DateTime.Now;
int retrycount = 0;
try
{
netezzaConn = new OleDbConnection(connString);
netezzaConn.Open();
for (int i = 0; i < recordCounts.Count; i++)
{
try
{
if (recordCounts[i].RecordCount.ToString() != recordCounts[i].OrigCount.ToString())
{
string updateStatement = string.Format("UPDATE fct_ourtable SET LINESWRITTENTOFILE = {0} where EXTRACTFILENAME = '{1}' and LINESWRITTENTOFILE = {2}", recordCounts[i].RecordCount.ToString(), recordCounts[i].FileName, recordCounts[i].OrigCount.ToString());
Console.WriteLine("Executing query : " + updateStatement);
Console.WriteLine("Query start-time - " + DateTime.Now.ToString());
OleDbCommand exe = new OleDbCommand(updateStatement, netezzaConn);
exe.CommandTimeout = 2000;
int rowsUpdated;
rowsUpdated = exe.ExecuteNonQuery();
Console.WriteLine("Rows Updated = " + rowsUpdated.ToString());
Console.WriteLine("Query end-time - " + DateTime.Now.ToString());
Console.WriteLine();
}
else
{
Console.WriteLine("No records were removed from the file : " + recordCounts[i].FileName + ". Not updating Netezza.");
Console.WriteLine();
}
}
catch (OleDbException oledbex)
{
retrycount++;
if (retrycount > 3)
{
Console.WriteLine("Maximum number of retrys met. Canceling now.");
throw new System.Exception();
}
else
{
i = i - 1;
Console.WriteLine("Timeout on Query, retrying");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
NetezzaWorkFailed();
}
finally
{
if (netezzaConn != null)
{
netezzaConn.Close();
netezzaConn = null;
}
TimeSpan duration = DateTime.Now.Subtract(Prequery);
Console.WriteLine("Query Time: " + duration);
}
}
}
}
This may be more appropriate as a comment but I don't have enough rep.
I haven't used OleDB much but we run queries in a similar manner to what you're doing with ODBC and haven't had any issues. It would be interesting to try at least.
A few comments on your snippet, which I doubt will have much effect on your problem but will help clarify and shorten the code.
Call Dispose instead of Close on your connection.
Also Dispose your command object.
Use parameters instead of formatting a query string (works for OleDB and ODCB). Create your OleDBCommand outside the loop and add your three parameters. Inside the loop you set the Value of the parameters and execute the query as you do already.
Use using blocks instead of try-catch to avoid the explicit calls to Dispose. You will still need a try-catch block inside or outside the using block if you want to handle exceptions.

How to access BIOS information from a Windows 8 app?

I know we can get the BIOS information using system.management assembly but the assembly is not accessible for windows 8 app. I specifically need to know the serial number of the laptop on which the app is running. Is there any way that I can access that ?
I don't think there is a way if you are developing a Windows Modern UI App.
Modern UI Apps get run in a sandbox environment which have very limited access to anything. Check MSDN documentations on that.
If you are developing a desktop Windows app on the other hand, then try the following code:
(You need to import System.Management.dll into your project.)
using System;
using System.IO;
using System.Management;
namespace GetHardwareIds
{
internal class Program
{
private static void Main(string[] args)
{
using (StreamWriter writer = new StreamWriter(#"C:\HardwareInfo.txt"))
{
using
(
ManagementObjectSearcher searcher =
// Where __Superclass Is Null: selects only top-level classes.
// remove it if you need a list of all classes
// new ManagementObjectSearcher("Select * From meta_class Where __Superclass Is Null")
// this query only select the processor info. for more options uncomment top line
new ManagementObjectSearcher("Select * From meta_class Where __Class = 'Win32_Processor'")
)
{
foreach (ManagementObject managementObject in searcher.Get())
{
Console.WriteLine(managementObject.Path.ClassName);
writer.WriteLine(managementObject.Path.ClassName);
GetManagementClassProperties(managementObject.Path.ClassName, writer);
managementObject.Dispose();
}
}
}
}
public static void GetManagementClassProperties(string path, StreamWriter writer)
{
using (ManagementClass managementClass = new ManagementClass(path))
{
foreach (ManagementObject instance in managementClass.GetInstances())
{
foreach (PropertyData property in instance.Properties)
{
Console.WriteLine(" {0} = {1}", property.Name, property.Value);
writer.WriteLine(" {0} = {1}", property.Name, property.Value);
}
instance.Dispose();
}
}
}
}
}
Check this code. I am not a 100% clear on what you are trying to achieve but this code should return the device ID specified by Win8 (this code includes a concatenation of all ids.)
// get hardware token
HardwareToken token = HardwareIdentification.GetPackageSpecificToken(null);
// get hardware ID bytes
byte[] idBytes = hwToken.Id.ToArray();
// populate device ID as a string value
string deviceID = string.Join(",", idBytes);
Here is the link to MSDN articles about it:
http://msdn.microsoft.com/en-us/library/windows/apps/jj553431.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.profile.hardwareidentification.getpackagespecifictoken.aspxThere is an entry for BIOS in the return structure based on these articles.
Hopefully, this does what you need. Let me know if it worked :)
Unfortunately the information you want to obtain is not available to WinRT applications.

Retrieving Total amount of RAM on a computer [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C# - How do you get total amount of RAM the computer has?
The following would retrieve how much ram is available:
PerformanceCounter ramCounter;
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
Console.WriteLine("Total RAM: " + ramCounter.NextValue().ToString() + " MB\n\n");
Of course we will have to use the System.Diagnostics; class.
Does performancecounter have any functionality for retrieving the amount of RAM of a particular machine? I'm not talking about the amount of ram used or unused. I'm talking about the amount of ram the machine has.
This information is already available directly in the .NET framework, you might as well use it. Project + Add Reference, select Microsoft.VisualBasic.
using System;
class Program {
static void Main(string[] args) {
Console.WriteLine("You have {0} bytes of RAM",
new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory);
Console.ReadLine();
}
}
And no, it doesn't turn your C# code into vb.net.
you can try like this
Add a Reference to System.Management.
private static void DisplayTotalRam()
{
string Query = "SELECT MaxCapacity FROM Win32_PhysicalMemoryArray";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(Query);
foreach (ManagementObject WniPART in searcher.Get())
{
UInt32 SizeinKB = Convert.ToUInt32(WniPART.Properties["MaxCapacity"].Value);
UInt32 SizeinMB = SizeinKB / 1024;
UInt32 SizeinGB = SizeinMB / 1024;
Console.WriteLine("Size in KB: {0}, Size in MB: {1}, Size in GB: {2}", SizeinKB, SizeinMB, SizeinGB);
}
}

CPU temperature monitoring

For a programming project I would like to access the temperature readings from my CPU and GPUs. I will be using C#. From various forums I get the impression that there is specific information and developer resources you need in order to access that information for various boards. I have a MSI NF750-G55 board. MSI's website does not have any of the information I am looking for. I tried their tech support and the rep I spoke with stated they do not have any such information. There must be a way to obtain that info.
Any thoughts?
For at least the CPU side of things, you could use WMI.
The namespace\object is root\WMI, MSAcpi_ThermalZoneTemperature
Sample Code:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSAcpi_ThermalZoneTemperature");
ManagementObjectCollection collection =
searcher.Get();
foreach(ManagementBaseObject tempObject in collection)
{
Console.WriteLine(tempObject["CurrentTemperature"].ToString());
}
That will give you the temperature in a raw format. You have to convert from there:
kelvin = raw / 10;
celsius = (raw / 10) - 273.15;
fahrenheit = ((raw / 10) - 273.15) * 9 / 5 + 32;
The best way to go for hardware related coding on windows is by using WMI which is a Code Creator tool from Microsoft, the tool will create the code for you based on what you are looking for in hardware related data and what .Net language you want to use.
The supported langauges currently are: C#, Visual Basic, VB Script.
Note that MSAcpi_ThermalZoneTemperature does not give you the temperature of the CPU but rather the temperature of the motherboard. Also, note that most motherboards do not implement this via WMI.
You can give the Open Hardware Monitor a go, although it lacks support for the latest processors.
internal sealed class CpuTemperatureReader : IDisposable
{
private readonly Computer _computer;
public CpuTemperatureReader()
{
_computer = new Computer { CPUEnabled = true };
_computer.Open();
}
public IReadOnlyDictionary<string, float> GetTemperaturesInCelsius()
{
var coreAndTemperature = new Dictionary<string, float>();
foreach (var hardware in _computer.Hardware)
{
hardware.Update(); //use hardware.Name to get CPU model
foreach (var sensor in hardware.Sensors)
{
if (sensor.SensorType == SensorType.Temperature && sensor.Value.HasValue)
coreAndTemperature.Add(sensor.Name, sensor.Value.Value);
}
}
return coreAndTemperature;
}
public void Dispose()
{
try
{
_computer.Close();
}
catch (Exception)
{
//ignore closing errors
}
}
}
Download the zip from the official source, extract and add a reference to OpenHardwareMonitorLib.dll in your project.

Categories

Resources