"Not found" exception generated while trying to get CPU ID via WMI - c#

I'm using this code to fetch the processor id:
public static string getProcessorId()
{
var mc = new ManagementClass("Win32_Processor");
var moc = mc.GetInstances();
foreach (var mo in moc)
{
return mo.Properties["ProcessorId"].Value.ToString();
}
return "Unknown";
}
I'm running Windows 7 32-bit, Visual Studio 2008.
Unfortunately, a "Not found" exception is being raised by the mc.GetInstances() method call.
Here's a similar bit of code (fetch HDD serial):
public static string getVolumeSerialNumber()
{
var disk = new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");
disk.Get();
return disk["VolumeSerialNumber"].ToString();
}
This code also fails - the "disk.Get()" method raises an "Invalid class" exception.
I've run this code with UAC turned off & on - nothing helps.
What am I doing wrong?

You WMI installation seems somewhat broken, I have tested your getProcessorId code on a Windows 7 with UAC on, and it works fine. "Win32_Processor" is a really standard class that should be there.
Here is a link to help diagnose WMI issues: How to check the WMI repository before rebuilding it

Related

Getting error 32775 while applying latest snapshot on HyperV VM using WMI

I am constantly getting error 32775 (Invalid state for this operation) when I try to revert my VMs to latest snapshot using WMI. I am using the following code (which is provided on MSDN website by the way):
ManagementObject virtualSystemService = Utility.GetServiceObject(connectionScope,"Msvm_VirtualSystemManagementService");
ManagementBaseObject inParams =virtualSystemService.GetMethodParameters("ApplyVirtualSystemSnapshot");
ManagementObject vmSnapshot = GetLastVirtualSystemSnapshot(vm);
if (vmSnapshot != null)
{
inParams["SnapshotSettingData"] = vmSnapshot.Path.Path;
inParams["ComputerSystem"] = vm.Path.Path;
ManagementBaseObject outParams = virtualSystemService.InvokeMethod("ApplyVirtualSystemSnapshot", inParams, null);
if ((UInt32)outParams["ReturnValue"] == ReturnCode.Started)
{
if (Utility.JobCompleted(outParams, connectionScope))
{
Console.WriteLine("Snapshot was applied successfully.");
}
else
{
Console.WriteLine("Failed to apply snapshot.");
}
}
else if ((UInt32)outParams["ReturnValue"] == ReturnCode.Completed)
{
Console.WriteLine("Snapshot was applied successfully.");
}
else
{
Console.WriteLine("Apply virtual system snapshot failed with error {0}", outParams["ReturnValue"]);
}
}
else
{
Console.WriteLine("No Snapshots!");
}
I can apply snapshots on the UI with no problem, and my VMs are in enabled state and are not doing anything. OS is Windows 2012. I can also print the name of snapshots and VMs so there are no problems in identifying machines and snapshots.
any ideas?
Thanks,
Shahab
Found out the problem, apparently the VM needs to be turned off if you want to apply your snapshots remotely! maybe it was too hard to mention that on MSDN website.

Why does Visual Studio run code after my breakpoint during a debug session?

I am working on a project in c# that using threading to initialize multiple calls to xcopy to copy user directories from one workstation to a network location.
When I run the program in debug mode, sometimes if I have a break-point BEFORE the program hits the calls to XCopy, and I stop the debugging with the stop button (in VS 2010), the program will then proceed to call the XCopy function, even though I stopped it from reaching the calls in the code. If I stop inside the foreach loop does the debugger continue to do the other foreach instances?
I know it sounds crazy, but has anyone else ever experienced this, or might you offer some suggestions that would correct this from happening?
A second issue with this is that when I run it from my Win7 machine accessing an XP machine in Firefox, the osInfo is correct, but when my boss runs it on his Win7 machine in IE, it doesn't work. It makes sense to me that the lines:
System.OperatingSystem osInfo = System.Environment.OSVersion;
if (dir_base.Exists && (osInfo.Platform == System.PlatformID.Win32NT)) //XP
Should be pulling the system that is running the code, not the network location's operating system type, but the if statement results in true when I run it and false when he does...
Here is my code:
public static void BuildSources_Targets(string Source, string str_Target )
{
//XP:
string str_basePath = Path.Combine(Source, "Documents and Settings");
var dir_base = new DirectoryInfo(str_basePath);
System.OperatingSystem osInfo = System.Environment.OSVersion;
if (dir_base.Exists && (osInfo.Platform == System.PlatformID.Win32NT)) //XP
{
foreach (var dir in dir_base.GetFileSystemInfos())
{
switch (dir.ToString())
{
case "administrator":
case "Administrator":
case "Default User":
case "All Users":
//Do nothing
break;
default:
string str_dir = dir.ToString();
//Handle XP App Data
//str_baseAndDirsPath = Path.Combine(dir_base.ToString(), str_dir, Environment.SpecialFolder.ApplicationData.ToString());
string str_baseAndDirsPath = Path.Combine(dir_base.ToString(), str_dir, "Application Data");
DirectoryInfo dir_baseAndDirs = new DirectoryInfo(str_baseAndDirsPath);
if (dir_baseAndDirs.Exists)
{
string str_Destination = Path.Combine(str_Target, str_dir, "Application Data");
ProcessXcopy(str_baseAndDirsPath, str_Destination);
}
//Handle XP Documents
str_baseAndDirsPath = Path.Combine(dir_base.ToString(), str_dir, "My Documents");
dir_baseAndDirs = new DirectoryInfo(str_baseAndDirsPath);
if (dir_baseAndDirs.Exists)
{
string str_Destination = Path.Combine(str_Target, str_dir, str_dir + " Documents");
ProcessXcopy(str_baseAndDirsPath, str_Destination);
}
break;
} //end of switch
} //end of foreach
} //end of dir_base.exists
//it continues from here...but that's enough to illustrate my problem...

WMI sometimes takes indefinite periods on local machine

I use a WMI in a couple of places in a few applications but sometimes the application gets stuck at the WMI get method. When this happens nothing seems to be able to recover it except for a machine restart. Stopping debugging / ending process in task manager and then restarting the application causes it to hang at the same point. Once WMI has started hanging no application is able to get any results. Waiting for WMI to recover takes an indefinite amount of time and never seems to amount to any following improvements until a machine restart.
A couple of my code extracts:
GetInstances() is where this code hangs.
public static ChassisTypes GetCurrentChassisType()
{
ManagementClass systemEnclosures = new ManagementClass("Win32_SystemEnclosure");
ManagementObjectCollection results = systemEnclosures.GetInstances();
foreach (ManagementObject obj in results)
{
foreach (int i in (UInt16[])(obj["ChassisTypes"]))
{
if (i > 0 && i < 25)
{
return (ChassisTypes)i;
}
}
}
return ChassisTypes.Unknown;
}
Get() is where this code hangs.
public static string GetOSInfo()
{
System.Management.ManagementObjectSearcher objMOS = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
try
{
foreach (ManagementObject objManagement in objMOS.Get())
{
// Do stuff to build OS version string
}
}
catch (Exception)
{
}
return OSName;
}
How do I stop the calls from hanging and freezing the rest of WMI?
You have to be sure you're using right WMI instructions. Try debugging you app with breakpoints to find out what may be wrong.
Nice WMI usage sample (Task Manager) (sources available for download) on my blog (written in Russian) may help you

Im using Win32_Fan to get and display my Cpu Fan Speed but it's not working why?

This is the code im calling the method in my Form1 constructor:
private void cpuFanSpeed()
{
SelectQuery query =
new SelectQuery("Win32_Fan");
// Instantiate an object searcher
// with this query
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(query);
// Call Get() to retrieve the collection
// of objects and loop through it
foreach (ManagementObject envVar in searcher.Get())
MessageBox.Show(envVar["DesiredSpeed"].ToString());
}
But it's never get to the MessageBox.
What is wrong here ? I tried to read and doing it by the document here: http://msdn.microsoft.com/en-us/library/aa394146(v=vs.85).aspx
And here: http://msdn.microsoft.com/en-us/library/ms257359.aspx
But it's not working.
I want to display my cpu fan speed every second on a label.
This is a screenshot of OpenHardwareMonitor display my cpu fan speed:
And this is the code the function im using in my application to get the CPU temperature:
In class:
public static float? cpuView(bool pause , CpuTemperature cpuTemp , Form1 f1 , List<string> myData , float? myCpuTemp , Button b1)
{
if (pause == true)
{
}
else
{
Computer myComputer = new Computer();
myComputer = new Computer(cpuTemp)
{
CPUEnabled =
true
};
myComputer.Open();
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.Temperature)
{
sensor.Hardware.Update();
cpuTemp.GetValue("sensor", sensor.Value.ToString());
f1.Invoke(new Action(() => myData.Add("Cpu Temeprature --- " + sensor.Value.ToString())));
myCpuTemp = sensor.Value;
if (sensor.Value > 60)
{
Logger.Write("The Current CPU Temperature Is ===> " + sensor.Value);
b1.Enabled = true;
}
break;
}
}
}
}
}
return myCpuTemp;
}
Not every machine provides this information through WMI. If your computer doesn't, you won't be able to access it. Just because WMI provides a property to access a particular piece of information doesn't mean that information will always be available.
Presumably, the collection you're iterating through in the foreach loop is empty, which is why no MessageBox ever gets displayed.
The only possible fix for this problem would be to obtain an updated driver from your motherboard manufacturer that provides WMI with this information (assuming, of course, that your hardware even includes the sensors required to measure this type of thing in the first place).
Edit: Open Hardware Monitor has apparently written its own drivers to interact directly with your hardware, querying its sensors. This suspicion is confirmed by perusing their web page, which documents specific pieces of hardware that it supports.
It's not using WMI to obtain its information, so this doesn't prove that you'll be able to obtain the information from WMI yourself.
However, the bottom of the above-linked page does contain this interesting remark:
The Open Hardware Monitor publishes all sensor data to WMI (Windows Management Instrumentation). This allows other applications to read and use the sensor information as well. A preliminary documentation of the interface can be found here.
So it appears that you can piggyback on top of Open Hardware Monitor, using its drivers to retrieve information, and then retrieve that information from it inside of your app. That's probably the best solution, since I doubt your hardware manufacturer is going to come through with an updated driver that provides the fan speed to WMI.

Which is faster to get running processes WMI or System.Diagnostics.Process?

I'm developing a small remote task manager application [server/client] on LAN using WCF service lib.
I need to know which way is faster to get processors information:
getting processes info from System.Diagnostics?
getting processes info from WMI?
I'm using the first options now, but if the application is x86, and the process is x64 then I can't access to Process.MainModule, so it forces me to create two versions of my application to get it work on any PC, x86 version and x64.
So if I used WMI would I face the same issue?
public void GetProcesses()
{
foreach (Process p in Process.GetProcesses())
{
try
{
InfoProcess process = new InfoProcess(p.Id, p.MainModule.ModuleName, p.MainModule.FileVersionInfo.FileDescription, p.WorkingSet / 1024);
PrintProcess(process);
}
catch
{ }
}
}
public class InfoProcess
{
public int Id;
public string Name;
public string Description;
public int WorkingSet;
public InfoProcess(int Id, string Name, string Desc, int WorkingSet)
{
this.Id = Id;
this.Name = Name;
this.Description = Desc;
this.WorkingSet = WorkingSet;
}
}
If WMI is better, I need a little help with properties names that gives me:
Process.WorkingSet
Process.MainModule.FileVersionInfo.FileDescription
I would expect WMI to be slower. There are some tricks that you can use to speed up WMI, but in general, performance is often poor.
In your situation I would simply build your app targeting AnyCPU. Then you have a single app that runs as x86 under a 32 bit OS and as x64 under a 64 bit OS. That way you can avoid WMI altogether.

Categories