Does anybody know where I can find any recent samples for using OpenHardwareMonitor.dll in C#.
I've tried a simple implementation but cannot get the cpu Temp. I know the library must have it since the app itself gets the temperature.
I have a feeling you have to register events to get readings on certain things but I'm finding it difficult to find a good example.
Computer myComputer = new Computer();
myComputer.Open();
foreach (var hardwareItem in myComputer.Hardware)
{
if (hardwareItem.HardwareType == HardwareType.CPU)
{
foreach (var sensor in hardwareItem.Sensors)
{
if (sensor.SensorType == SensorType.Temperature)
{
Console.WriteLine(sensor.Value);
}
}
}
}
Any thoughts or insight would be appreciated.
Below is as far as I got. I don't have more time to spend on it, so I'll leave the rest of the sleuthing to you.
I couldn't find any documentation whatsoever. There are not even XML comments in the code, so I dug through the source code to get as far as I did. You're going to have to do the same.
The first thing you're missing is that you have to set the Computer.CPUEnabled property to true before you call Computer.Open. This causes Open to add a CPU hardware device.
The second thing you're missing is that you have to call Computer.Open.
The third thing you're missing is that you have to call Hardware.Update to get it to re-poll the hardware.
The fourth thing you're missing is that the sensor value is a Nullable<float>. You have to check that there is a valid value there.
This still isn't enough. Although it now outputs four temperature sensors (on my machine), there never is a temperature value.
I dug through the settings and found that there are these long initialization items for the cpu and cpu's temperature. I added code to put those settings into the Computer (at least for one of the cores), but it didn't have any effect.
What is failing is this call in IntelCpu.Update
Ring0.RdmsrTx(IA32_THERM_STATUS_MSR, out eax, out edx, 1UL << cpuid[i][0].Thread)
That's why I suspect there is some initialization missing.
Good Luck!
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
using OpenHardwareMonitor.Hardware;
namespace WindowsFormsApplication1
{
public class MySettings : ISettings
{
private IDictionary<string, string> settings = new Dictionary<string, string>();
public MySettings(IDictionary<string, string> settings)
{
this.settings = settings;
}
public bool Contains(string name)
{
return settings.ContainsKey(name);
}
public string GetValue(string name, string value)
{
string result;
if (settings.TryGetValue(name, out result))
return result;
else
return value;
}
public void Remove(string name)
{
settings.Remove(name);
}
public void SetValue(string name, string value)
{
settings[name] = value;
}
}
public class Form1 : Form
{
Computer myComputer;
Timer timer = new Timer { Enabled = true, Interval = 1000 };
public Form1()
{
timer.Tick += new EventHandler(timer_Tick);
MySettings settings = new MySettings(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=" },
});
myComputer = new Computer(settings) { CPUEnabled = true };
myComputer.Open();
}
void timer_Tick(object sender, EventArgs e)
{
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)
{
if (sensor.SensorType == SensorType.Temperature)
{
Trace.WriteLine(String.Format("{0} Temperature = {1}", sensor.Name, sensor.Value.HasValue ? sensor.Value.Value.ToString() : "no value"));
}
}
}
}
}
}
}
Apologies for not adding this as a comment for the previous answer but I don't have enough reputation.
Just incase anyone else bumps into this like I did and has the same problem, I have found a solution to the problem not all CPU info displaying by simply running Visual Studio /the compiled program with administrative rights.
It seems the low level API calls that are needed to get the CPU information is not possible without administrative rights, but no error is displayed.
Related
because of having always open Oracle connections and want to track them down using performance counters. Because of missing admin rights I can't use the perfmon.
I googled and just found 1 promissing example but I can't manage to get it running and would really appreciate your help!
the performance Monitoring class (pmc) looks like this:
List<PerformanceCounter> lstPerfCounters = new List<PerformanceCounter>();
public virtual void InitializeCounters(string AppInstanceName, Type PerfCountersList)
{
foreach (string counterName in Enum.GetNames(PerfCountersList))
{
PerformanceCounter PerfCounter = new PerformanceCounter();
PerfCounter.CategoryName = ".NET Data Provider for SqlServer";
PerfCounter.CounterName = counterName;
PerfCounter.InstanceName = AppInstanceName;
lstPerfCounters.Add(PerfCounter);
}
}
public virtual void PrintCounters()
{
foreach (PerformanceCounter p in lstPerfCounters)
{
Console.WriteLine("{0} = {1}", p.CounterName, p.NextValue());
}
Console.WriteLine("****************************************************************");
}
and has those enums:
public enum DBPerformanceCounters
{
NumberOfActiveConnectionPools,
NumberOfActiveConnections,
NumberOfFreeConnections,
NumberOfNonPooledConnections,
NumberOfPooledConnections,
SoftDisconnectsPerSecond,
SoftConnectsPerSecond,
NumberOfReclaimedConnections,
HardConnectsPerSecond,
HardDisconnectsPerSecond,
NumberOfActiveConnectionPoolGroups,
NumberOfInactiveConnectionPoolGroups,
NumberOfInactiveConnectionPools,
NumberOfStasisConnections
}
When starting my Programm I wanted to initialise it with the code given
PMC pc = new PMC();
string InstanceName = "myProgram";
pc.InitializeCounters(InstanceName, typeof(CountersList.DBPerformanceCounters));
pc.PrintCounters();
and here is the problem: the ide tells me, that CountersList doesn't exist. If I create a List for the DBPerformanceCounter manually, I get told that it is a varibale that is used like a type.
I'm sure its just a small bug, but I'm clueless and would really appreciate your help!
Thanks in advance.
*Earased some typos.
I have a C# program (actually it's just a C# library that is being used by NUnit) that I wish to modify slightly which is based off of this article: How to Programmatically move items in outlook. I'm currently faced with a folder that has bout 3500 messages all around 350kb and is taking FOREVER to move to my archive so I can send and receive emails again (since my inbox is currently at 1.5Gb out of 500Mb... lol) but for the life of me I can't figure out how to get my archive folder. I'm a little bit multitasking since I'm at work so I can edit as I go. So if you have any code readily available that finds the archive folder that would be great. Thank you
EDIT
ok to show that I do have some work in progress (based on negative feedback) here is the code I have in place right now (since yes I know I have a give me teh codez)
here is my NUnit test case that looks at a folder and gives me specific information
[Test]
public void CheckMessages()
{
List<EmailMessage> messages = new List<EmailMessage>();
using (var target = new EmailMessageProvider())
{
messages.AddRange(target.GetEmailMessages("UnexpectedErrors\\NotFindImage"));
}
Dictionary<int, string> asdf = new Dictionary<int, string>();
foreach (var item in messages)
{
var line = item.Body.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[2];
var revisionId = int.Parse(Regex.Match(line, #"\-*\d+").Value);
var path = line.Substring(line.IndexOf("\\\\"));
if (asdf.ContainsKey(revisionId))
{
Assert.That(path, Is.EqualTo(asdf[revisionId]));
}
else
{
asdf.Add(revisionId, path);
}
}
foreach (var item in asdf.OrderBy(x => x.Key))
{
Console.WriteLine($"{item.Key} {item.Value}");
}
}
I use the same class to find messages (in another test) and move it to that subfolder which that test is using.
here is the code I have that does the moving
public void MoveSurveyPrintComponentsNotFound()
{
var destination = _baseFolder.Folders["UnexpectedErrors"].Folders["NotFindImage"];
foreach (var mailItem in _baseFolder.Folders["UnexpectedErrors"].Items.OfType<MailItem>())
{
mailItem.UseMailItem(x =>
{
if (x.Body.Contains("Foobar.Common.Exceptions.ImageNotFound"))
x.Move(destination);
});
}
}
EDIT 2
looks like I may have just about got it. I found that in the MAPI Namspace one of the subfolders is Archives. I'm going to try to change a few of the variables and see if it moves. Problem is just checking one folder takes over 31 seconds. oh well. better than never.
I figured it out. It wasn't as hard as I had thought either so I'll share what i have just incase someone else has this problem. In my program I did 2 things. One was to set _basefolder as my default email address's Folder. Second was to to set _mapi to the Outlook.GetNamespace("MAPI"). Those two thinsg I already had in my constructor.
private readonly OutlookApplication _outlook;
private readonly NameSpace _mapi;
private MAPIFolder _baseFolder;
public EmailMessageProvider()
{
_outlook = new OutlookApplication();
_mapi = _outlook.GetNamespace("MAPI");
_baseFolder = _mapi.Folders["robert#defaultEmail.com"];
}
Archives works just like any other MAPIFolder so it's just a matter of getting said folder. For me it was in _mapi.Folders["Archive"]. I would imagine this is fairly standard so if you copy and paste it should work just fine.
So now to list out all of my emails I want to go through and move tham appropriatly.
public void MoveSpecificEmailsToArchives()
{
var destination = _mapi.Folders["Archives"];
foreach (var mailItem in _baseFolder.Folders["Unexpected Error"].Items.OfType<MailItem>())
{
mailItem.UseMailItem(x =>
{
if (x.Body.Contains("offensiveProgram.exe ERROR "))
x.Move(destination);
});
}
Release(destination);
}
fyi the UseMailItem is an extension method. Looks like this
public static void UseMailItem(this MailItem item, Action<MailItem> mailItemAction)
{
mailItemAction(item);
Marshal.ReleaseComObject(item);
}
Today I hit an issue while using a reference in C#. My use-case is the following: I have a global configuration-object in a winform-application. When opening the settings-screen, the settings-part of the object gets deep-cloned. At the time of clicking the save button, the element should get saved back to the original reference. This is not working as I first expected it to.
I have prepared a dotnet-fiddle for you to take a look at the problem. If someone is aware of a way to solve this problem, I am more than thankful for your input. I am thankful for pointing me to the correction too (I am sure someone has solved this issue in a much much cleaner way).
1) We have an globally avaiable static object structure
2) At a point in time, a part of this structure should be deattached from the object structure
3) The deattached part will be edited
4) At a later point in time, the part MAYBE should be reattached to the original reference in the object structure again
I am a frontend developer and its pretty hard to express my problem with words, so take a look at my code:
https://dotnetfiddle.net/qzJqC4
--- For readers from the far future where links are a thing of the past ---
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
namespace DemoCloneAndReattach
{
[Serializable]
public class DogFamily
{
public DogFamily()
{
PrettyDogs = new List<PrettyDog>();
}
public List<PrettyDog> PrettyDogs { get; set; }
}
[Serializable]
public class PrettyDog
{
public string Name { get; set; }
public int NumberOfEars { get; set; }
}
public class Program
{
public static void Main(string[] args)
{
// Note: The WriteLines will help you to validate the correctness of the solution. Thanks a lot!
// Setting up
DogFamily dogFamily = new DogFamily();
dogFamily.PrettyDogs.Add(new PrettyDog() { Name = "OriginalDog", NumberOfEars = 2 });
// Getting the dog with the name "OriginalDog"
PrettyDog originalDog = dogFamily.PrettyDogs.FirstOrDefault(o => o.Name == "OriginalDog");
originalDog.NumberOfEars = 3;
Console.WriteLine("originalDog has NumberOfEars (expected 3): " + originalDog.NumberOfEars);
// Checking if the originalDog in the List has the value updated (from 2 to 3). It does.
PrettyDog checkDogOne = dogFamily.PrettyDogs.FirstOrDefault(o => o.Name == "OriginalDog");
Console.WriteLine();
Console.WriteLine("checkDogOne has NumberOfEars (expected 3): " + checkDogOne.NumberOfEars);
// Now creating a deep-clone of the originalDog (this will result in a brand new object, not related to the DogFamily in any way)
PrettyDog clonedDog = DeepClone<PrettyDog>(originalDog);
// Doing something that should not YET be written to the DogFamily-reference tree.
clonedDog.NumberOfEars = 7;
// Checking if the clonedDog has not the same reference as the originalDog. As expected, it hasn't.
Console.WriteLine();
Console.WriteLine("clonedDog has NumberOfEars (expected 7): " + clonedDog.NumberOfEars);
Console.WriteLine("originalDog still has NumberOfEars (expected 3): " + originalDog.NumberOfEars);
// I want the behavior below, but automated (some kind of reverse-matching or -reattaching-logic to the reference of originalDog):
originalDog.Name = clonedDog.Name;
originalDog.NumberOfEars = clonedDog.NumberOfEars;
// Maybe the call to the solution would look like this:
// Reattach<PrettyDog>(originalDog, clonedDog);
Console.WriteLine();
Console.WriteLine("originalDog now has NumberOfEars (expected 7): " + originalDog.NumberOfEars);
Console.WriteLine("clonedDog has still NumberOfEars (expected 7): " + clonedDog.NumberOfEars);
// Checking if the reference is set correctly (not only the originalDog-reference but the whole reference-tree)
PrettyDog checkDogTwo = dogFamily.PrettyDogs.FirstOrDefault(o => o.Name == "OriginalDog");
Console.WriteLine();
Console.WriteLine("checkDogTwo has NumberOfEars (expected 7 - this is the tricky one): " + checkDogTwo.NumberOfEars);
}
public static T DeepClone<T>(T obj)
{
if (obj == null) return default(T);
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T)formatter.Deserialize(ms);
}
}
public static void Reattach<T>(T original, T clone)
{
// Logic for replacing the original with the clone without damaging the reference-tree
}
}
}
I have a couple of load balanced application server running on IIS 7. I need to check how many webservice calls are made from each of the server. I also need to check this at a particular instance. Do we have some thing in .net which communicates with both the server and gives me the snapshot at a particular instance.
Thanks
You could use Perfmon to add statistics regarding the number of calls. Once you're doing that you could also add timing data as well... You can then use Perfmon on the local box or hook up to it remotely with any number of tools.
Sorry I can't point you to specifics -- I've only seen it done, not done it myself :) But I think it is pretty straightforward.
And some sample code, showing how you could implement performance counters:
using System;
using System.Configuration;
using System.Diagnostics;
namespace TEST
{
// sample implementation
public static class PerformanceHelper
{
// update a performance counter value
public static void UpdateCounter(string WebMethodName, int count)
{
// to be able to turn the monitoring on or off
if (ConfigurationManager.AppSettings["PerformanceMonitor"].ToUpper() == "TRUE")
{
PerformanceCounter counter;
if (!PerformanceCounterCategory.Exists("SAMPLE"))
{
CounterCreationDataCollection listCounters = new CounterCreationDataCollection();
CounterCreationData newCounter = new CounterCreationData(WebMethodName, WebMethodName, PerformanceCounterType.NumberOfItems64);
listCounters.Add(newCounter);
PerformanceCounterCategory.Create("SAMPLE", "DESCRIPTION", new PerformanceCounterCategoryType(), listCounters);
}
else
{
if (!PerformanceCounterCategory.CounterExists(WebMethodName, "SAMPLE"))
{
CounterCreationDataCollection rebuildCounterList = new CounterCreationDataCollection();
CounterCreationData newCounter = new CounterCreationData(WebMethodName, WebMethodName, PerformanceCounterType.NumberOfItems64);
rebuildCounterList.Add(newCounter);
PerformanceCounterCategory category = new PerformanceCounterCategory("SAMPLE");
foreach (var item in category.GetCounters())
{
CounterCreationData existingCounter = new CounterCreationData(item.CounterName, item.CounterName, item.CounterType);
rebuildCounterList.Add(existingCounter);
}
PerformanceCounterCategory.Delete("SAMPLE");
PerformanceCounterCategory.Create("SAMPLE", "DESCRIPTION", new PerformanceCounterCategoryType(), rebuildCounterList);
}
}
counter = new PerformanceCounter("SAMPLE", WebMethodName, false);
if (count == -1)
counter.IncrementBy(-1);
else
counter.IncrementBy(count);
}
}
}
}
Is it possible to read the publisher name of the currently running ClickOnce application (the one you set at Project Properties -> Publish -> Options -> Publisher name in Visual Studio)?
The reason why I need it is to run another instance of the currently running application as described in this article and pass parameters to it.
Of course I do know my application's publisher name, but if I hard code it and later on I decide to change my publisher's name I will most likely forget to update this piece of code.
Here is another option. Note that it will only get the publisher name for the currently running application, which is all I need.
I'm not sure if this is the safest way to parse the XML.
public static string GetPublisher()
{
XDocument xDocument;
using (MemoryStream memoryStream = new MemoryStream(AppDomain.CurrentDomain.ActivationContext.DeploymentManifestBytes))
using (XmlTextReader xmlTextReader = new XmlTextReader(memoryStream))
{
xDocument = XDocument.Load(xmlTextReader);
}
var description = xDocument.Root.Elements().Where(e => e.Name.LocalName == "description").First();
var publisher = description.Attributes().Where(a => a.Name.LocalName == "publisher").First();
return publisher.Value;
}
You would think this would be trivial, but I don't see anything in the framework that gives you this info.
If you want a hack, you can get the publisher from the registry.
Disclaimer - Code is ugly and untested...
...
var publisher = GetPublisher("My App Name");
...
public static string GetPublisher(string application)
{
using (var key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Uninstall"))
{
var appKey = key.GetSubKeyNames().FirstOrDefault(x => GetValue(key, x, "DisplayName") == application);
if (appKey == null) { return null; }
return GetValue(key, appKey, "Publisher");
}
}
private static string GetValue(RegistryKey key, string app, string value)
{
using (var subKey = key.OpenSubKey(app))
{
if (!subKey.GetValueNames().Contains(value)) { return null; }
return subKey.GetValue(value).ToString();
}
}
If you find a better solution, please follow-up.
I dont know about ClickOnce, but normally, you can read the assembly-info using the System.Reflection framework:
public string AssemblyCompany
{
get
{
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
if (attributes.Length == 0)
{
return "";
}
return ((AssemblyCompanyAttribute)attributes[0]).Company;
}
}
Unfortunately, theres no "publisher" custom-attribute, just throwing this out as a possible work-around