Detect HDMI connection when we are using setup box using c# - c#

I am using wpf application inside one of the windows media player, so when I use the following code to detect HDMI connection it always show disconnect as that HDMI connection denotes as primary connection. When i use HDMI connection in laptop this work well, can some one suggest code chnages for above case
public static int HdmiConnectionStatus()
{
int HDMI_Monitors = 0;
ManagementClass mClass = new ManagementClass(#"\\localhost\ROOT\WMI:WmiMonitorConnectionParams");
Log.Info("HdmiConnectionStatus ManagementClass ");
if(mClass != null)
{
Log.Info(mClass);
foreach (ManagementObject mObject in mClass.GetInstances())
{
var ss = mObject["VideoOutputTechnology"];
Log.Info("HdmiConnectionStatus HDMI port Info :" + ss);
if (ss.ToString().StartsWith("5"))
{
int HDMIport = Convert.ToInt32(ss);
if (HDMIport == 5)
{
HDMI_Monitors += 1;
}
}
}
}
else
{
Log.Info(" HdmiConnectionStatus Null ManagementClass ");
}
return HDMI_Monitors;
}

I can see you are using very specific value 5 to get the HDMI connection, when you connect the HDMI cable in Laptop you will get two values in mObject , one will be laptop screen and another is HDMI value 5, but in case of setup box this case will not remain same, check the port number for your setup box , it can be 5 or 10
I tried on my setup box and I got value 10 and here is the code
public static int HdmiConnectionStatus()
{
int HDMI_Monitors = 0;
ManagementClass mClass = new ManagementClass(#"\\localhost\ROOT\WMI:WmiMonitorConnectionParams");
Log.Info("HdmiConnectionStatus ManagementClass ");
if(mClass != null)
{
Log.Info(mClass);
foreach (ManagementObject mObject in mClass.GetInstances())
{
var ss = mObject["VideoOutputTechnology"];
Log.Info("HdmiConnectionStatus HDMI port Info :" + ss);
if (ss.ToString().StartsWith("5") || ss.ToString().StartWith("10"))
{
int HDMIport = Convert.ToInt32(ss);
if (HDMIport == 5 || HDMIport == 10)
{
HDMI_Monitors += 1;
}
}
}
}
else
{
Log.Info(" HdmiConnectionStatus Null ManagementClass ");
}
return HDMI_Monitors;
}

Related

How to get all devices in Network within Unity?

For around 8 hours now already I am trying to find a way so that I can receive all devices which are in the same network as I am. I've already found a few ways to do this, but all of them boil down to ping all IPs in the network. That wouldn't be a big problem if Unity allowed multithreading. Due to the fact that it does not / basically only allows IEnumerator I have the problem that I have to execute each ping after another which needs alot of time in which you cant even use the GUI.
My Current Code looks like this:
public class AddressFinder {
private List<Ping> pingers = new List<Ping>();
private List<IPAddress> addresses = new List<IPAddress>();
private int timeOut = 250;
private int ttl = 5;
private int instances;
private MonoBehaviour m;
public void Scan(MonoBehaviour mono, IPSegment ips, Action<List<IPAddress>> callback) {
this.m = mono;
m.StartCoroutine(ScanAsync(ips, callback)); // New Coroutine so the UI should not freeze
}
private IEnumerator ScanAsync(IPSegment ips, Action<List<IPAddress>> callback) {
PingOptions po = new PingOptions(ttl, true);
byte[] data = new System.Text.ASCIIEncoding().GetBytes("abababababababababababababababab");
instances = 0;
foreach(uint host in ips.Hosts()) { // Itterate through all IPs in that network
m.StartCoroutine(Send(IPHelper.ToIpString(host) // IP as String, data, po));
}
WaitForSeconds wait = new WaitForSeconds(0.05f);
while(instances > 0) {
yield return wait;
}
callback(addresses);
}
private IEnumerator Send(string ip, byte[] data, PingOptions po) {
instances++;
Ping p = new Ping();
PingReply rep = p.Send(ip, timeOut, data, po);
p.Dispose();
if(rep.Status == IPStatus.Success)
addresses.Add(IPAddress.Parse(ip));
instances--;
yield return new WaitForSeconds(0);
}
}
This wcode will actually work but needs like 4 mins to test all 253 IPs in my network. Also the UI freezes during this time.
I also tried using the unity Ping which seemed very inconsistent and also did not work that well, cause it also needed much to long for 254 pings.
Does anyone have an idea what the problem is or has another idea to get all devices in the network?
I have found a way with threads. I actually thought one should not use threads in Unity but it seems to just not use Unity Operations outside of the main Thread, mean others are allowed. Anyways here is my Code:
using Ping = System.Net.NetworkInformation.Ping;
public class AddressFinder {
public List<string> addresses = new List<string>();
private MonoBehaviour m;
Thread myThread = null;
public int instances = 0;
public AddressFinder(MonoBehaviour mono) {
m = mono;
}
public void Scan(List<IPSegment> iPSegments, Action<List<string>> addresses) {
myThread = new Thread(() => ScanThreads(iPSegments, addresses));
myThread.Start();
}
private void ScanThreads(List<IPSegment> iPSegments, Action<List<string>> callback) {
Ping myPing;
PingReply reply;
instances = 0;
foreach(IPSegment ips in iPSegments) {
foreach(uint hosta in ips.Hosts()) {
string ip = IPHelper.ToIpString(hosta);
Task.Factory.StartNew(() => {
myPing = new Ping();
instances++;
reply = myPing.Send(ip, 250);
if(reply.Status == IPStatus.Success) {
addresses.Add(ip);
}
instances--;
}, TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning);
}
}
int i = 0;
while(instances > 0) {
if(i > 100)
break;
i++;
Thread.Sleep(10);
}
callback(addresses);
}
}
public class LobbyManager : MonoBehaviour {
public UnityEngine.Object[] Games;
private List<string> localAddresses = new List<string>();
private List<string> hostAddresses = new List<string>();
private Ping p;
AddressFinder af;
public void Start() {
List<IPSegment> iPSegments = GetInterfaces(true);
af = new AddressFinder(this);
af.Scan(
iPSegments,
(addresses) => {
localAddresses = addresses;
foreach(string address in localAddresses) {
Debug.Log(address.ToString());
}
}
);
}
public void Update() {
}
public List<IPSegment> GetInterfaces(bool showVPN) {
List<IPSegment> ipsList = new List<IPSegment>();
foreach(NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) {
if(ni.Name.Contains("VM") || ni.Name.Contains("Loopback"))
continue;
if(!showVPN && ni.Name.Contains("VPN"))
continue;
foreach(UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) {
if(ip.Address.AddressFamily == AddressFamily.InterNetwork) {
IPSegment ips = new IPSegment(ip.Address.ToString(), ip.IPv4Mask.ToString());
ipsList.Add(ips);
}
}
}
return ipsList;
}
}
IPSegment is a class where all IPs in this segment according to the subnetmask are saved in.
This code works kinda well but is not that performent which means that there should not be a higher Subnetmask than 255.255.255.0 or it will need ages.

USBDeviceInfo/ManagementObjectSearcher gives Arguments that where´nt asked for

I have some code i wrote for finding the COM-Port of a certain Motor-Controller, based off of this Article:
Getting Serial Port Information
Since this Code doesn´t explicitely look for ComPorts, but for Device Names and Infos, I played around a bit and found out that when you look for a certain device in the resulting list, referenced by name, and write that to a *.txt file, the COMPort shows up in (brackets) after the name, like so: Devicename (COM5).
This I used to write that information to a string using Array.Find, and from then on it´s just selecting the number to connect to.
My Problem is that i don´t want to loop through ALL devices, but just until the one I´m looking for is found, and then break the loop.
This, however, results in a string[1] Array without the COMPort attached to entries, opposed to a string[2] Array with ComPort attached if I don´t break the loop.
I want to know why the COMPort gets attached in the first place (my guess is collection.Dispose), and why breaking the loop kills that "function/bug/whatever".
{
public static void ComPortSelectionMain(/*string[] args*/)
{
string ComDummy; // ComPort, ComPortString;
int ComNumber = 0;
var usbDevices = GetUSBDevices();
var ComList = new List<string>();
foreach (var usbDevice in usbDevices)
{
if (usbDevice.Description == "PI C-863")
{
//Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}", usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description);
ComList.Add(usbDevice.Name); //Add USB Device
}
}
var ComArray = ComList.ToArray();
var target = "PI C-863 (COM";
// var target2 = ")";
int arrayindex = 0;
int start = 0, stop = 0;
string targetname = "PI C-863";
string test = (Array.Find(ComArray, element => element.Contains(targetname)));
//Console.WriteLine("Test: " + test);
if (test == targetname) //look if comarray contains target
{
//int index = Array.FindIndex(ComArray, item => item == "("); // row.Contains(targetname));
int indexsigned = Array.IndexOf(ComArray, target);
int index = Math.Abs(indexsigned);
start = ComArray[index].IndexOf('(') + 1;
arrayindex = index;
stop = ComArray[index].IndexOf(')');
}
int COMlength = 0, portlength = 0, pos = 0;
COMlength = stop - start;
portlength = stop - start - 3;
pos = start + 3;
//Console.WriteLine("COM: {0}", ComArray[arrayindex]);
ComDummy = ComArray[arrayindex].Substring(start, COMlength);
//Console.WriteLine("ComDummy: {0}", ComDummy);
ComNumber = Convert.ToInt32(ComArray[arrayindex].Substring(pos, portlength));
Console.WriteLine("ComPort Number: {0}", ComNumber);
Console.Read();
}
static List<USBDeviceInfo> GetUSBDevices()
{
List<USBDeviceInfo> devices = new List<USBDeviceInfo>();
ManagementObjectCollection collection;
using (var searcher = new ManagementObjectSearcher(#"Select * From Win32_PnPEntity"))
collection = searcher.Get();
bool kappa = true;
foreach (var device in collection)
{
devices.Add(new USBDeviceInfo(
(string)device.GetPropertyValue("DeviceID"),
(string)device.GetPropertyValue("PNPDeviceID"),
(string)device.GetPropertyValue("Description"),
(string)device.GetPropertyValue("Name"),
(string)device.GetPropertyValue("Service")
));
***//if ((devices.Exists(element => element.Description == "PI C-863")) && kappa)
//{
// Console.WriteLine("Found PI C-863!");
// kappa = false;
// //break;
//}*** <<< THIS IF() BREAKS MY CODE
}
collection.Dispose();
return devices;
}
}
class USBDeviceInfo
{
public USBDeviceInfo(string deviceID, string pnpDeviceID, string description, string name, string var)
{
this.DeviceID = deviceID;
this.PnpDeviceID = pnpDeviceID;
this.Description = description;
this.Name = name;
this.Var = var;
}
public string DeviceID { get; private set; }
public string PnpDeviceID { get; private set; }
public string Description { get; private set; }
public string Name { get; private set; }
public string Var { get; private set; }
}
The if(devices.Exist) question breaks my code if I use it and let if break the loop, can somebody explain why, and what i could do?
(Code works fine so far, but not being able to break the loop slows it down quite a bit)
Thanks in advance :)
Regards, Cinnabar
You should try :
static List<USBDeviceInfo> GetUSBDevices()
{
ManagementObjectCollection collection;
using (var searcher = new ManagementObjectSearcher(#"Select * From Win32_PnPEntity"))
collection = searcher.Get();
foreach (var device in collection)
{
if(device.GetPropertyValue("Description").Equals("PI C-863"))
{
Console.WriteLine("Found PI C-863!");
break;
}
}
collection.Dispose();
return devices;
}
I did not test it, but i think iterating over a List while adding into it could be the issue.
SerialPort.GetPortNames() reads the comports on computer. Use following code to read the comports and fill combo box (dropdown).
private void refreshPortChoices()
{
int selectedPortIndex = this.cbbPortName.SelectedIndex;
this.cbbPortName.Items.Clear();
this.cbbPortName.Items.AddRange(SerialPort.GetPortNames());
if (selectedPortIndex < this.cbbPortName.Items.Count)
{
this.cbbPortName.SelectedIndex = selectedPortIndex;
}
if (this.cbbPortName.Items.Count == 0)
{
this.cbbPortName.Items.Add("none");
this.btnConnection.Enabled = false;
}
else
{
this.btnConnection.Enabled = true;
}
}

Why im getting all the time InvalidOperationException?

I know what does it mean but i don't understand why i'm getting it.
In my class constructor i did:
namespace HM
{
class Core
{
public static Form1 form1;
Process[] pname;
private static List<float?> cpuSensorValues = new List<float?>();
private static List<float?> gpuSensorValues = new List<float?>();
Computer myComputer;
Computer computer;
public Core(Form1 f)
{
form1 = f;
myComputer = new Computer();
myComputer.CPUEnabled = true;
myComputer.FanControllerEnabled = true;
myComputer.MainboardEnabled = true;
myComputer.Open();
computer = new Computer();
computer.Open();
computer.GPUEnabled = true;
OpenHardwareMonitor.Hardware.ISensor isss;
Hardwares hwsd;
OpenHardwareMonitor.Hardware.ISensor ist;
pname = Process.GetProcessesByName("BFBC2Game");
}
I added this:
pname = Process.GetProcessesByName("BFBC2Game");
And when the game is running i see using a breakpoint that pname wontain one index that is the game process. And im sure to run first the game then the program.
Then i have a method in the class i call it with a timer in Form1 that get write to a log file the temeperature of the GPU Video Card.
This part was working good untill i added this pname process.
if (gpuSensorValues.Count == 30 && sensor.Value >= (float)numericupdown)
{
float a = ComputeStats(gpuSensorValues).Item1;
float b = ComputeStats(gpuSensorValues).Item2;
float c = ComputeStats(gpuSensorValues).Item3;
Logger.Write("********************************");
Logger.Write("GPU Minimum Temperature Is ===> " + a);
Logger.Write("GPU Maximum Temperature Is ===> " + b);
Logger.Write("GPU Average Temperature Is ===> " + c);
Logger.Write("********************************" + Environment.NewLine);
gpuSensorValues = new List<float?>();
pname.ToList().ForEach(p => p.Kill());
}
I added this :
pname.ToList().ForEach(p => p.Kill());
I wanted that if the temperature for example was 123c then kill/close/shut down the game at once ! Instead it's not writing to the logger file the temperature anymore and it's never kill the process but writing to the log file the exception message:
3/5/2014--4:10 AM ==> There was an exception: System.InvalidOperationException: No process is associated with this object.
at System.Diagnostics.Process.EnsureState(State state)
at System.Diagnostics.Process.EnsureState(State state)
at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited)
at System.Diagnostics.Process.Kill()
at HardwareMonitoring.Core.gpuView(Boolean pause, List`1 myData, Nullable`1 myGpuTemp, Button b1, Decimal numericupdown) in d:\C-Sharp\HardwareMonitoring\HardwareMonitoring\Hardwaremonitoring\Core.cs:line 172
This is the complete method code if needed:
public float? gpuView(bool pause, List<string> myData, float? myGpuTemp, Button b1, decimal numericupdown)
{
try
{
if (pause == true)
{
}
else
{
foreach (var hardwareItem in computer.Hardware)
{
if (form1.videoCardType("ati", "nvidia") == true)
{
HardwareType htype = HardwareType.GpuNvidia;
if (hardwareItem.HardwareType == htype)
{
foreach (var sensor in hardwareItem.Sensors)
{
if (sensor.SensorType == SensorType.Temperature)
{
sensor.Hardware.Update();
if (sensor.Value.ToString().Length > 0)
{
/* else if (UpdatingLabel(sensor.Value.ToString(), label16.Text.Substring(0, label16.Text.Length - 1)))
{
// Label8 = GpuText;
}*/
//myData = new List<string>();
//this.Invoke(new Action(() => data = new List<string>()));
if (!form1.IsDisposed)
{
form1.Invoke(new Action(() => myData.Add("Gpu Temeprature --- " + sensor.Value.ToString())));
}
//this.Invoke(new Action(() => listBox1.DataSource = null));
//this.Invoke(new Action(() => listBox1.DataSource = data));
//form1.Invoke(new Action(() => lb1.DataSource = myData));
//sensor.Value.ToString() + "c";
myGpuTemp = sensor.Value;
//label8.Visible = true;
}
//if (sensor.Value > 60)
//{
gpuSensorValues.Add(sensor.Value);
if (gpuSensorValues.Count == 30 && sensor.Value >= (float)numericupdown)
{
float a = ComputeStats(gpuSensorValues).Item1;
float b = ComputeStats(gpuSensorValues).Item2;
float c = ComputeStats(gpuSensorValues).Item3;
Logger.Write("********************************");
Logger.Write("GPU Minimum Temperature Is ===> " + a);
Logger.Write("GPU Maximum Temperature Is ===> " + b);
Logger.Write("GPU Average Temperature Is ===> " + c);
Logger.Write("********************************" + Environment.NewLine);
gpuSensorValues = new List<float?>();
pname.ToList().ForEach(p => p.Kill());
}
b1.Enabled = true;
//}
//form1.Select();
}
}
}
}
else
{
HardwareType htype = HardwareType.GpuAti;
if (hardwareItem.HardwareType == htype)
{
foreach (var sensor in hardwareItem.Sensors)
{
if (sensor.SensorType == SensorType.Temperature)
{
sensor.Hardware.Update();
if (sensor.Value.ToString().Length > 0)
{
myGpuTemp = sensor.Value;
//label8.Visible = true;
}
if (sensor.Value > 60)
{
Logger.Write("The Current Ati GPU Temperature Is ===> " + sensor.Value);
b1.Enabled = true;
}
form1.Select();
}
}
}
}
}
}
}
catch (Exception err)
{
Logger.Write("There was an exception: " + err.ToString());
}
return myGpuTemp;
}
Line 172 is:
//form1.Select();
Just empty line nothing to do there.
The docs for Process.Kill() show that it can raise an InvalidOperationException if the process is not running.
Maybe try: pname.Where(p => !p.HasExited).ToList().ForEach(p => p.Kill());
The problem is that one or more of the instances in your pname list aren't in the state you expect. As pointed out in another answer this could be because the process isn't running. Also, one of the references could be null. To prevent the exception try adding a where clause like the following;
pname.ToList().Where(p != null && !p.HasExited).ForEach(p => p.Kill());
I'm not familiar with the Process class so I'm not entirely sure what you'll want to use for that second condition in the Where but that should give you the idea. This will just filter out instances in the list that would cause the error before calling Kill().
The only problem i can see in your code is you are not clearing the pname object. If the pname has reference to a process that is no longer running, you will get this exception. I recommend to get fresh list of process when you want to stop it. Replace the following line
pname.ToList().ForEach(p => p.Kill());
with
pname = Process.GetProcessesByName("BFBC2Game");
pname.ToList().ForEach(p => p.Kill());

How do i get the cpu fan speed using the OpenHardwareMonitor lib?

I referenced my project with OpenHardwareMonitor.dll
And then created new class with this code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenHardwareMonitor.Hardware;
using System.Diagnostics;
using DannyGeneral;
using System.Windows.Forms;
using System.Threading;
namespace HardwareMonitoring
{
class Core
{
public static Form1 form1;
private static List<float?> cpuSensorValues = new List<float?>();
private static List<float?> gpuSensorValues = new List<float?>();
Computer myComputer;
Computer computer;
public Core(Form1 f)
{
form1 = f;
myComputer = new Computer();
myComputer.CPUEnabled = true;
myComputer.Open();
computer = new Computer();
computer.Open();
computer.GPUEnabled = true;
}
public float? cpuView(bool pause , CpuTemperature cpuTemp , Form1 f1 , List<string> myData , float? myCpuTemp , Button b1)
{
try
{
if (pause == true)
{
}
else
{
Trace.WriteLine("");
foreach (var hardwareItem in myComputer.Hardware)
{
if (hardwareItem.HardwareType == HardwareType.CPU)
{
hardwareItem.Update();
foreach (IHardware subHardware in hardwareItem.SubHardware)
subHardware.Update();
foreach (var sensor in hardwareItem.Sensors)
{
cpuTemp.SetValue("sensor", sensor.Value.ToString());
if (sensor.SensorType == SensorType.Fan)//Temperature)
{
sensor.Hardware.Update();
cpuTemp.GetValue("sensor", sensor.Value.ToString());
if (!f1.IsDisposed)
{
Thread.Sleep(1000);
f1.Invoke(new Action(() => myData.Add("Cpu Temeprature --- " + sensor.Value.ToString())));
}
myCpuTemp = sensor.Value;
//if (sensor.Value > 60)
//{
cpuSensorValues.Add(sensor.Value);
if (cpuSensorValues.Count == 300)
{
float a = ComputeStats(cpuSensorValues).Item1;
float b = ComputeStats(cpuSensorValues).Item2;
float c = ComputeStats(cpuSensorValues).Item3;
Logger.Write("********************************");
Logger.Write("CPU Minimum Temperature Is ===> " + a);
Logger.Write("CPU Maximum Temperature Is ===> " + b);
Logger.Write("CPU Average Temperature Is ===> " + c);
Logger.Write("********************************" + Environment.NewLine);
cpuSensorValues = new List<float?>();
}
b1.Enabled = true;
//}
break;
}
}
}
}
}
}
catch(Exception err)
{
Logger.Write("There was an exception: " + err.ToString());
}
return myCpuTemp;
}
On the line:
if (sensor.SensorType == SensorType.Fan)//Temperature)
If i'm using the Temperature it's working fine and showing the temperature.
But once i change it to Fan the SensorType never == to the Fan
And if i'm running the original openhardwaremonitor program it's showing all the stuff even the cpu fan speed.
So why in my code it's not working ?
EDIT**
Forgot to mention that in Form1 at the top i have:
private CpuTemperature cpu;
Then in the constructor:
cpu = new CpuTemperature(new Dictionary<string, string>
{
{ "/intelcpu/0/temperature/0/values", "H4sIAAAAAAAEAOy9B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Iu6//MH37x79i9/+NX6N3/TJm9/5f/01fw1+fosnv+A/+OlfS37/jZ/s/Lpv9fff6Ml/NTef/yZPnozc5679b+i193//TQZ+/w2Dd+P9/sZeX/67v/GTf/b3iP3u4/ObBL//73+i+f039+D8Zk/+xz/e/P6beu2TQZju8yH8f6OgzcvPv/U3/Rb8+z/0f/9b/+yfaOn8079X6fr6Cws7ln/iHzNwflPv99/wyS/+xY4+v/evcJ+733+jJ5//Cw7/4ndy9Im3+U2e/Fbnrk31C93vrt/fyPvdb+N//hsF7/4/AQAA//9NLZZ8WAIAAA==" },
{ "/intelcpu/0/load/0/values", "H4sIAAAAAAAEAOy9B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/Iu6//MH37x79i9++mpwcv/md/9df89egZ/xX/ym/5y/4D37618Lv7ya//u+58+u+5d9/z7/5t/w9/6u5fP5bH/6av+eTkXyefXxp26ONaf/v/dG/sf39D/rvnv4e5vc/0IP56/waK/vuHzf5I38P8/tv+mv8Rbb9f0pwTF9/zr/1X9vP/8I//+/6Pf7Z30N+/zdf/HX29zd/859q4aCNP5b//U+U3/+7f+zXOjZwfqvDX/V7/o9/vPz+a1G/pv0f+fGlhfk7eZ//N3/0v28//5X0u/n8Cxq7+f1X/tHft20A5x8a/W5/02+BP36Nf+j/nv8XfzrT+c2//Ob4p3+vktvUhNs/+xcWikP6e/4T/5jS5M8/sL8vP/5ff49f/Ivl9//sHzv6PX/vXyG//9R/94/9HuZ34P/5vyC//3W/5e/1exa/k+Bw4bUBnU2bP4Xg/1bn0uafeTH6PatfKL//N3/0t2y/gG9+/8+IzqYNxmU+/+jwX7afY67/nwAAAP//GYSA31gCAAA=" },
});
Maybe there should be something like this for the FAN of the cpu but i couldn't find any.
So i wonder how they use it in the original openhwardwaremonitor.
Tried to search in the source code : http://open-hardware-monitor.googlecode.com/svn/trunk/GUI/
But i didn't find how to get the cpu/gpu fans speed.
For anybody still struggling with this, you first have to enable the mainboard in your OpenHardwareMonitor.Hardware.Computer object:
Computer computerHardware = new Computer();
computerHardware.MainboardEnabled = true;
You then have to search 2 hardware layers deep.
By this I mean:
foreach (var hardware in computerHardware.Hardware)
{
// This will be in the mainboard
foreach (var subhardware in hardware.SubHardware)
{
// This will be in the SuperIO
subhardware.Update();
if (subhardware.Sensors.Length > 0) // Index out of bounds check
{
foreach (var sensor in subhardware.Sensors)
{
// Look for the main fan sensor
if (sensor.SensorType == SensorType.Fan && sensor.Name.Equals("Fan #1", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("CPU Fan Speed:" + Convert.ToString((int)(float)sensor.Value) + " RPM");
}
}
}
}
}
It is very important that you have the subhardware.update(); call in there, otherwise you will only see control type sensors (I know from painful experience).
I hope this helps.
References:
SuperIO
Mainboard
Looks like you need the following to turn on the fan reader:
computer.FanControllerEnabled = true;
You're only looking for sensors nested inside the CPU object.
There actually are temperature sensors inside the CPU, but the fans are neither inside the CPU nor connected to it. Your "CPU fan" is called that because it's physically placed atop the CPU to cool it.
Look for Fan sensors elsewhere in the tree. On my system they're displayed within the motherboard object. You'll find additional measurements of CPU temperature there as well, from sensors placed on the outside of the CPU module. The CPU voltage as well is sensed outside the CPU, at least on my system, and therefore nested within the motherboard and not the CPU in the hardware monitoring tree.
As bland noted, the myComputer.CPUEnabled = true; may not be sufficient to enable the rest of the sensor tree.

Monitor (Display) Names and Bounds

My app has the ability to use a dual monitor configuration. In the app's settings I list the available displays where the user will choose his secondary screen.
I'm getting the (real) monitor device names using:
http://msdn.microsoft.com/en-us/library/aa394122%28VS.85%29.aspx
SelectQuery q = new SelectQuery("SELECT Name, DeviceID, ScreenHeight, ScreenWidth FROM Win32_DesktopMonitor");
using (ManagementObjectSearcher mos = new ManagementObjectSearcher(q))
{
foreach (ManagementObject mo in mos.Get())
{
...
}
}
But I also need the display bounds (top, left, etc) which this doesn't give me. But System.Windows.Forms.Screen does give me bounds but not real device names. I could use these together if I am certain that they return the devices in the same order every time. Will both of these always return "Device 1", "Device 2", etc in chronological order every time? Or is there a way that contains all my needed information?
[edit]
Hmm. Win32_DesptopMonitor isnt giving me my secondary monitors name. Its just calling it Default Monitor. And it's listing it before my primary.
[edit2]
Ok it's got the names and their resolutions messed up..... Anyone know whats going on here?
I have done this before using Win API calls. I pasted bits of the code below, which might be helpful to you...
public void Store()
{
Screens.Clear();
uint iAdaptorNum = 0;
Win.User32.DISPLAY_DEVICE adaptor = new Win.User32.DISPLAY_DEVICE();
adaptor.cb = (short)Marshal.SizeOf(adaptor);
Win.User32.DISPLAY_DEVICE dd = new Win.User32.DISPLAY_DEVICE();
dd.cb = (short)Marshal.SizeOf(dd);
while (Win.User32.EnumDisplayDevices(null, iAdaptorNum, ref adaptor, Win.User32.EDD_GET_DEVICE_INTERFACE_NAME))
{
uint iDevNum = 0;
while (Win.User32.EnumDisplayDevices(adaptor.DeviceName, iDevNum, ref dd, Win.User32.EDD_GET_DEVICE_INTERFACE_NAME))
{
log.WriteFormat(LogLevel.Debug, "Adaptor {0}:{1} {2}='{3}', Device {4}='{5}', State flags = {4}",
iAdaptorNum, iDevNum, adaptor.DeviceName, adaptor.DeviceString, dd.DeviceName, dd.DeviceString, dd.StateFlags);
if ((dd.StateFlags & Win.User32.DisplayDeviceStateFlags.AttachedToDesktop) > 0)
Screens.Add(new ScreenInfo(adaptor, dd));
iDevNum++;
}
iAdaptorNum++;
}
}
And this is what gets called behind new ScreenInfo:
public void StoreScreen(Win.User32.DISPLAY_DEVICE Adaptor, Win.User32.DISPLAY_DEVICE Device)
{
adaptor = Adaptor.DeviceName;
device = Device.DeviceName;
name = string.Format("{0} on {1}", Device.DeviceString, Adaptor.DeviceString);
Win.User32.DEVMODE dm = newDevMode();
if (Win.User32.EnumDisplaySettings(Adaptor.DeviceName, Win.User32.ENUM_CURRENT_SETTINGS, ref dm) != 0)
{
isAttached = (Adaptor.StateFlags & Win.User32.DisplayDeviceStateFlags.AttachedToDesktop) > 0;
isPrimary = (Adaptor.StateFlags & Win.User32.DisplayDeviceStateFlags.PrimaryDevice) > 0;
mode = findMode(Adaptor.DeviceName, dm);
if ((dm.dmFields & Win.User32.DM.PelsWidth) > 0) width = dm.dmPelsWidth;
if ((dm.dmFields & Win.User32.DM.PelsHeight) > 0) height = dm.dmPelsHeight;
if ((dm.dmFields & Win.User32.DM.BitsPerPixel) > 0) bpp = dm.dmBitsPerPel;
if ((dm.dmFields & Win.User32.DM.Orientation) > 0) orientation = dm.dmOrientation;
if ((dm.dmFields & Win.User32.DM.DisplayFrequency) > 0) frequency = dm.dmDisplayFrequency;
if ((dm.dmFields & Win.User32.DM.DisplayFlags) > 0) flags = dm.dmDisplayFlags;
if ((dm.dmFields & Win.User32.DM.Position) > 0)
{
posX = dm.dmPosition.x;
posY = dm.dmPosition.y;
}
}
}
private static Win.User32.DEVMODE newDevMode()
{
Win.User32.DEVMODE dm = new Win.User32.DEVMODE();
dm.dmDeviceName = new String(new char[31]);
dm.dmFormName = new String(new char[31]);
dm.dmSize = (short)Marshal.SizeOf(dm);
return dm;
}

Categories