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.
Related
I am trying to figure out how to check if a webcam/video capture device is already being used by another application without actually activating it.
My current approach is to use the AForge.NET library and using the .IsRunning property of the VideoCaptureDevice object like this:
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo videoDevice in videoDevices)
{
VideoCaptureDevice camera new AForge.Video.DirectShow.VideoCaptureDevice(videoDevice.MonikerString);
Debug.Print(camera.IsRunning)
}
I guess the IsRunning property only works on VideoCaptureDevices that have been started using the library and I need lower-level DirectShow access to the device.
While there are many ways to use DirectShow in C#, I have been unable to find a way to check the state even using DirectShow in C++. Is there some magic I need to perform here?
Thanks
Tobias Timpe
I'm not entirely sure if this will be helpful to you, but I found your question because I wanted to write a custom app to control my busylight. This is very much 'Works On My Machine' certified - it's not an attempt to give a general answer. However, I figure it may help you, and possibly the next person who comes across this page while googling...
private static bool IsWebCamInUse()
{
using (var key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam\NonPackaged"))
{
foreach (var subKeyName in key.GetSubKeyNames())
{
using (var subKey = key.OpenSubKey(subKeyName))
{
if (subKey.GetValueNames().Contains("LastUsedTimeStop"))
{
var endTime = subKey.GetValue("LastUsedTimeStop") is long ? (long) subKey.GetValue("LastUsedTimeStop") : -1;
if (endTime <= 0)
{
return true;
}
}
}
}
}
return false;
}
i am new to WIA. And i have been asked to make scaning service scan faster and duplex. My current service scan one page, then put it in pdf and so on untill there is less then 20 pages(this number just a crutch used before me, will be glad if someone explane how to get "if there is any paper in there" variable). I started to dig and found docs on MSDN describing properties and after found this post describing duplex sanning, but with mysterious 5 in set. After I found this and figured out what i need WIA_DPS_DOCUMENT_HANDLING_SELECT to set to 0x205(FEEDER + DUPLEX + AUTO_ADVANCE). So I tried to setup them like this:
private static void SetProperty(Property property, int value)
{
IProperty x = (IProperty)property;
Object val = value;
x.set_Value(ref val);
}
...some code...
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
SetProperty(prop, 517);
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
And it did't worked for me... It just stuck on setting... Can Somebody explain how to setup AUTO_ADVANCE and DUPLEX props? Or maybe "make scanning faster and duplex" need something more then just AUTO_ADVANCE and DUPLEX and my perception about them is wrong? Or I should considering "ISIS / TWAIN (Windows XP / Vista / 7 / 8 / 8.1 / 10)" string in my scan description and use other libraries?
(Window 10, Canon DR-M160||, DR-M160 & DR-M160II Driver for Windows)
and also here is the current fetch function:
public List<ImageFile> FetchImageList()
{
List<ImageFile> imageList = new List<ImageFile>();
//bool hasMorePages = true;
int testcount = 0;
while (testcount >= 0)
{
testcount--;
WIA.Device device = FindDevice(_deviceId);
if (device == null)
{
LOGGER.Warn("Scanner device not found");
return null;
}
// get item
WIA.Item scanItem = device.Items[1] as WIA.Item;
LOGGER.Debug($"ScanItem: {scanItem.ItemID}");
try
{
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
LOGGER.Warn("here");
SetProperty(prop, 517);
LOGGER.Warn("here");
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
// scan image
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Front");
//get back side
image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Back");
}
catch (Exception e)
{
throw (e);
}
}
return imageList;
}
Well... I tried to make duplex scan without AUTO_ADVANCE and got HRESULT: 0x8000FFFF (E_UNEXPECTED) on Transfer call. According to this post(even though that was on Windows 7) I guess there is no way to solve this for me by using WIA, still hope there will other suggestions...
Solved problem
I used saraff.twain and it worked for me:
- git page :https://github.com/saraff-9EB1047A4BEB4cef8506B29BA325BD5A/Saraff.Twain.NET
good library with grate wiki page.(Also have similar library for .net 4.6.1)
I want to get the same hardware id in windows forms application that i get when i use UnityEngine.SystemInfo.deviceUniqueIdentifier in my game.
How can I get the same hardware id?
I know I'm late but Unity's SystemInfo::deviceUniqueIdentifier is built like this:
Requires: using System.Management; in System.Management.dll (.NET Framework)
private string GetDeviceUniqueIdentifier() {
string ret = string.Empty;
string concatStr = string.Empty;
try {
using ManagementObjectSearcher searcherBb = new ManagementObjectSearcher("SELECT * FROM Win32_BaseBoard");
foreach (var obj in searcherBb.Get()) {
concatStr += (string)obj.Properties["SerialNumber"].Value ?? string.Empty;
}
using ManagementObjectSearcher searcherBios = new ManagementObjectSearcher("SELECT * FROM Win32_BIOS");
foreach (var obj in searcherBios.Get()) {
concatStr += (string)obj.Properties["SerialNumber"].Value ?? string.Empty;
}
using ManagementObjectSearcher searcherOs = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
foreach (var obj in searcherOs.Get()) {
concatStr += (string)obj.Properties["SerialNumber"].Value ?? string.Empty;
}
using var sha1 = SHA1.Create();
ret = string.Join("", sha1.ComputeHash(Encoding.UTF8.GetBytes(concatStr)).Select(b => b.ToString("x2")));
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
return ret;
}
I reverse engineered the Unity Editor to find out what it actually queries in the WMI.
This is obviously the Windows Implementation.
https://docs.unity3d.com/ScriptReference/SystemInfo-deviceUniqueIdentifier.html
SystemInfo.deviceUniqueIdentifier
Leave feedback
public static string deviceUniqueIdentifier;
Description
A unique device identifier. It is guaranteed to be unique for every device (Read Only).
iOS: on pre-iOS7 devices it will return hash of MAC address. On iOS7 devices it will be UIDevice identifierForVendor or, if that fails for any reason, ASIdentifierManager advertisingIdentifier.
Android: SystemInfo.deviceUniqueIdentifier always returns the md5 of ANDROID_ID. (See https://developer.android.com/reference/android/provider/Settings.Secure.html#ANDROID_ID). Note that since Android 8.0 (API level 26) ANDROID_ID depends on the app signing key. That means "unsigned" builds (which are by default signed with a debug keystore) will have a different value than signed builds (which are signed with a key provided in the player settings). Also when allowing Google Play to sign your app, this value will be different when testing locally built app which is signed with the upload key and app downloaded from the Google Play which will be signed with the "final" key.
Windows Store Apps: uses AdvertisingManager::AdvertisingId for returning unique device identifier, if option in 'PC Settings -> Privacy -> Let apps use my advertising ID for experiences across apps (turning this off will reset your ID)' is disabled, Unity will fallback to HardwareIdentification::GetPackageSpecificToken().Id.
Windows Standalone: returns a hash from the concatenation of strings taken from Computer System Hardware Classes (https://msdn.microsoft.com/en-us/library/windows/desktop/aa389273(v=vs.85).aspx):
Win32_BaseBoard::SerialNumber
Win32_BIOS::SerialNumber
Win32_Processor::UniqueId
Win32_DiskDrive::SerialNumber
Win32_OperatingSystem::SerialNumber
I am using NAudio for a screen recording software I am designing and I need to know if it's possible to not only control the specific application's volume but also display a VU Meter for the application's sound.
I've Googled all over the place and it seems I can only get a VU Meter for the devices currently on my computer and set the volume for those devices.
Even though I am using NAudio, I am open to other solutions.
I asked the question in more detail after this question. I have since found the answer so I will leave the answer here for those who stumble upon it. Trying to use NAudio & CSCore has gotten me quite familiar with so please ask if you need further assistance.
This block of code uses CSCore and is a modified and commented version of the answer found here:Getting individual windows application current volume output level as visualized in audio Mixer
class PeakClass
{
static int CurrentProcessID = 0000;
private static void Main(string[] args)
{
//Basically gets your default audio device and session attached to it
using (var sessionManager = GetDefaultAudioSessionManager2(DataFlow.Render))
{
using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
{
//This will go through a list of all processes uses the device
//the code got two line above.
foreach (var session in sessionEnumerator)
{
//This block of code will get the peak value(value needed for VU Meter)
//For whatever process you need it for (I believe you can also check by name
//but I found that less reliable)
using (var session2 = session.QueryInterface<AudioSessionControl2>())
{
if(session2.ProcessID == CurrentProcessID)
{
using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>())
{
Console.WriteLine(audioMeterInformation.GetPeakValue());
}
}
}
//Uncomment this block of code if you need the peak values
//of all the processes
//
//using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>())
//{
// Console.WriteLine(audioMeterInformation.GetPeakValue());
//}
}
}
}
}
private static AudioSessionManager2 GetDefaultAudioSessionManager2(DataFlow dataFlow)
{
using (var enumerator = new MMDeviceEnumerator())
{
using (var device = enumerator.GetDefaultAudioEndpoint(dataFlow, Role.Multimedia))
{
Console.WriteLine("DefaultDevice: " + device.FriendlyName);
var sessionManager = AudioSessionManager2.FromMMDevice(device);
return sessionManager;
}
}
}
}
The following code block will allow you to change the volume of the device using NAudio
MMDevice VUDevice;
public void SetVolume(float vol)
{
if(vol > 0)
{
VUDevice.AudioEndpointVolume.Mute = false;
VUDevice.AudioEndpointVolume.MasterVolumeLevelScalar = vol;
}
else
{
VUDevice.AudioEndpointVolume.Mute = true;
}
Console.WriteLine(vol);
}
I have code from two different libraries only to answer the question I posted directly which was how to both set the volume and get VU Meter values (peak values). CSCore and NAudio are very similar so most of the code here is interchangeable.
I am trying to write a C# code that outputs the current audio output level from each of the windows application accessing the sound output (as shown with constantly changing green bars of the Volume mixer).
The program will check every 10 ms, and outputs sth like this: Windows Media Player: 30, Mozilla Firefox: 0, Adobe Flash Player: 35 (as per the figure)
I am using Windows 7, and trying it in C# (as Java cannot achieve this).
I have found ways to get and set the Master Volume (the handle bar which shows 65% for Windows Media Player) for a running application, is there a way to get the green fluctuating level data?
Thank you!
You can use CSCore.
There is a wrapper for the CoreAudioAPI-Audiosessions. Use something like that (for more details take a look at the unittests: AudioSession-UnitTests):
private static void Main(string[] args)
{
using (var sessionManager = GetDefaultAudioSessionManager2(DataFlow.Render))
{
using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
{
foreach (var session in sessionEnumerator)
{
using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>())
{
Console.WriteLine(audioMeterInformation.GetPeakValue());
}
}
}
}
Console.ReadKey();
}
private static AudioSessionManager2 GetDefaultAudioSessionManager2(DataFlow dataFlow)
{
using (var enumerator = new MMDeviceEnumerator())
{
using (var device = enumerator.GetDefaultAudioEndpoint(dataFlow, Role.Multimedia))
{
Debug.WriteLine("DefaultDevice: " + device.FriendlyName);
var sessionManager = AudioSessionManager2.FromMMDevice(device);
return sessionManager;
}
}
}
To control an applications volume, take a look at the unit-tests here.
Here is a sample application which displays the audio levels from running applications in a graph. There are two versions, one in WPF and one in Windows.Forms. They use the method from Florian's answer to get the audio levels.
https://github.com/jeske/SoundLevelMonitor