This probably isn't the best way, but I am currently retrieving the amount of RAM on a machine using:
manageObjSearch.Query = new ObjectQuery("SELECT TotalVisibleMemorySize FROM Win32_OperatingSystem");
manageObjCol = manageObjSearch.Get();
foreach (ManagementObject mo in manageObjCol)
sizeInKilobytes = Convert.ToInt64(mo["TotalVisibleMemorySize"]);
It works well and good, but I feel I could be doing this more directly and without a foreach over a single element, but I can't figure out how to index a ManagementObjectCollection
I want to do something like this:
ManagementObject mo = new ManagementObject("Win32_OperatingSystem.TotalVisibleMemorySize")
mo.Get();
Console.WriteLine(mo["TotalVisibleMemorySize"].ToString())
or maybe even something like
ManagementClass mc = new ManagementClass("Win32_OperatingSystem");
Console.WriteLine(mc.GetPropertyValue("TotalVisibleMemorySize").ToString());
I just can't seem to figure it out. Any ideas?
The foreach statement is hiding the enumerator you need to access. You can do it directly like this:
var enu = manageObjSearch.Get().GetEnumerator();
if (!enu.MoveNext()) throw new Exception("Unexpected WMI query failure");
long sizeInKilobytes = Convert.ToInt64(enu.Current["TotalVisibleMemorySize"]);
Related
I am trying to help with a slow legacy application that gets certain data through the ManagementObjectCollection class. This function takes around 40 seconds, however it took a little over a minute when getting the data directly from the ManagementObjectCollection. We pared down the query and selected the data into a list which helped execution time, however it is still very slow considering how many elements are supposed to be here. I have the following code:
string baseStr;
ManagementObjectCollection moReturn;
ManagementObjectSearcher moSearch;
ManagementObjectSearcher moSearch32;
List<string> programs = new List<string>();
List<ProgramDescription> moList;
moSearch32 = new ManagementObjectSearcher("Select Name, Version, InstallDate from Win32_Product");
moReturn = moSearch32.Get();
moList = moReturn.Cast<ManagementObject>().AsEnumerable()
.Select(x => new ProgramDescription
{
Name = x["Name"],
Version = x["Version"],
InstallDate = x["installDate"]
}).ToList();
foreach (ProgramDescription currentMo in moList)
{
if (currentMo.Name == null)
continue;
else
{
baseStr = currentMo.Name.ToString() + ", " + currentMo.Version?.ToString()
+ ", " + currentMo.InstallDate?.ToString();
}
}
As you can see, I am attempting to convert this to a list of another object and iterate through that. However, I have noticed that even when doing this, the foreach loop takes an eternity despite the moList object only having ~290 items. The management object search and converting it to a list seem to happen instantly, but this iteration is still taking forever. Why is this? If this is just a quirk in relation to accessing these management objects, is there a more efficient way of getting this specific query?
I'm created method for collecting installed applications version info from windows OS. But facing slowness issue, when assign the value into foreach. Getting ManagementObjectSearcher result is faster. Any suggestion for my requirement?
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Product WHERE Name=Google Chrome");
foreach (ManagementObject obj in searcher.Get()) // this part is taking too long time to process
{
MessageBox.Show(obj["Name"] + "-----" + obj["Version"]);
};
I'm looking to get performance information for the disks on my local computer using WMI. According to the documentation for Win32_PerfFormattedData_PerfDisk_LogicalDisk (http://msdn.microsoft.com/en-us/library/aa394261(v=vs.85).aspx), it looks like I should just be able to query the information and get the values.
However, when I run the code I get "0" for each value for the properties.
var selectQuery = new SelectQuery("Select * from Win32_PerfFormattedData_PerfDisk_LogicalDisk");
var searcher = new ManagementObjectSearcher(selectQuery);
foreach (ManagementObject disk in searcher.Get())
{
foreach (PropertyData property in disk.Properties)
{
var propertyValue = property.Value; // 0 value.
}
}
I have also queried Win32_PerfRawData_PerfDisk_LogicalDisk and I do get actual raw values. Of course, I would rather have the formatted data instead of the raw data. The documentation for converting the raw data to the formatted data seems to be lacking when it comes to using WMI.
Any idea why I am getting 0 for each value?
Here is a working example just tested this
You can use the WMI Performance Class Counters. An example of this would be polling the PerfDisk_LogicalDisk
ManagementObjectSearcher mos = new ManagementObjectSearcher("select * from Win32_PerfFormattedData_PerfDisk_LogicalDisk");
foreach (ManagementObject service in mos.Get())
{
foreach (PropertyData propData in service.Properties)
{
Console.WriteLine("{0} {1}", propData.Name, propData.Value);
}
}
As far as I research on internet, I tried some codes but it's working. it returned '0' value. My question is:How can I get motherboard and CPU Voltage informations in C#?
My code:
//http://wutils.com/wmi/
//create a management scope object
ManagementScope scope = new ManagementScope("\\\\.\\ROOT\\cimv2");
//create object query
ObjectQuery query = new ObjectQuery("SELECT * FROM CIM_VoltageSensor");
//create object searcher
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope, query);
//get collection of WMI objects
ManagementObjectCollection queryCollection = searcher.Get();
//enumerate the collection.
foreach (ManagementObject m in queryCollection)
{
// access properties of the WMI object
Console.WriteLine("Accuracy : {0}", m["Accuracy"]);
}
Look at the OpenHardwareMonitor opensource project.
You may find this helpful. The explanation of the examples are here.
Look into frmMain.cs example.
This should be an easy one for Linq guru's.
I wanna retrieve all the physical printers that are available to a user. As far as I can tell there is no property/setting that you can query which tells you whether a printer is a physical of a virtual one. But there's already a question about that topic : Is there a possibility to differ virtual printer from physical one?
I'm using a reliable-ish way to see if it's a virtual one, and I check whether the "EnableBIDI" property is set to true.
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
ManagementObjectCollection coll = searcher.Get();
var installedPhysicalPrinters = new List<string>();
var scratch = from ...
The result should be that the installedPhysicalPrinters contains a list of installedprinter names.
I got this far
foreach (ManagementObject printer in coll)
{
var validPrinter = (from PropertyData p in printer.Properties
from ManagementObject pr in coll
where p.Name == "EnableBIDI" && (bool) p.Value == true
select p).FirstOrDefault();
if (validPrinter != null)
{
installedPrinters.Add(validPrinter.Value.ToString());
// this is just to see the properties
foreach (PropertyData property in printer.Properties)
{
lstMessages.Items.Add(string.Format("{0}: {1}", property.Name, property.Value));
}
}
}
Obviously this is wrong, and I end up with a list of "true" values in the list, instead of the printer names.
Using nested for eaches it's easy to solve, but that's sooo 2004...
The issue with combining LINQ and System.Management is that the latter uses older non-generic containers (like ManagementObjectCollection) that you can't use directly with LINQ because it uses the non-generic IEnumerable interface.
Luckily you can work around that, as in the following example:
static void Main(string[] args)
{
Func<PropertyData, bool> indicatesPhysical = property => property.Name == "EnableBIDI"; // && (bool) property.Value;
Func<ManagementBaseObject, bool> isPhysicalPrinter = obj => obj.Properties.OfType<PropertyData>().Any(indicatesPhysical);
var searcher = new ManagementObjectSearcher("Select * from Win32_Printer");
var collection = searcher.Get();
var physicalPrinters = collection.OfType<ManagementBaseObject>().Where(isPhysicalPrinter);
foreach (var item in physicalPrinters)
{
Console.WriteLine(item.Properties["DeviceID"].Value);
Console.WriteLine(item.Properties["EnableBIDI"].Value);
}
}
You can use the Enumerable.OfType<>() extension method to transform the specified IEnumerable interface into an IEnumerable<ManagementBaaseObject>. That will help in getting those queries along.
Your example on how to differentiate between physical and virtual printers didn't work on my end, but it's irrelevant to what the main problem is that you're dealing with, namely trying to make code more readable by using LINQ expressions.