This is a bit dated, but the question is about how you get (near) accurate processor information in Windows 2003 with WMI and no external executables.
I wrote this a long time ago for VBS and translated it into C# for my upcoming application: Astronomy. I added some snazzy XAML in there to pimp it out a bit. There is a lot of code here, but that is because a lot needs to be done to format the data into something we want to see.
The desired result:
So, let’s see all that code:
The XAML:
<Window x:Class="GetProcessCountLegacy.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="200" Width="525"> <Window.Resources> <!-- Text Styles --> <Style x:Key="ListHeader" TargetType="{x:Type TextBlock}"> <Setter Property="FontWeight" Value="Bold" /> </Style> <Style x:Key="ListLabel" TargetType="{x:Type TextBlock}"> <Setter Property="FontWeight" Value="Normal" /> </Style> <Style x:Key="ListValue" TargetType="{x:Type TextBlock}"> <Setter Property="FontWeight" Value="DemiBold" /> </Style> <!-- Border --> <Style x:Key="BorderStyle" TargetType="Border"> <Setter Property="BorderBrush" Value="#999" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="CornerRadius" Value="6" /> <Setter Property="Padding" Value="16,14,16,16" /> <Setter Property="Margin" Value="12,6,12,6" /> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush StartPoint="0.5, 0" EndPoint="0.5, 1" Opacity="1.0"> <GradientStop Color="#FFFFFF" Offset="0" /> <GradientStop Color="#FFFFFF" Offset="0.5" /> <GradientStop Color="#EDEDED" Offset="1" /> </LinearGradientBrush> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <!-- Processor Information --> <Border Style="{StaticResource BorderStyle}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="28"/> <RowDefinition Height="22"/> <RowDefinition Height="22"/> <RowDefinition Height="22"/> <RowDefinition Height="22"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="120"/> <ColumnDefinition Width="600"/> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Top" Text="Processor Information" Style="{StaticResource ListHeader}" /> <TextBlock Grid.Row="1" Grid.Column="0" Text="Description:" Style="{StaticResource ListLabel}" /> <TextBlock Grid.Row="1" Grid.Column="1" x:Name="txtDescription" Style="{StaticResource ListValue}" /> <TextBlock Grid.Row="2" Grid.Column="0" Text="Core Speed:" Style="{StaticResource ListLabel}" /> <TextBlock Grid.Row="2" Grid.Column="1" x:Name="txtSpeed" Style="{StaticResource ListValue}" /> <TextBlock Grid.Row="3" Grid.Column="0" Text="Count:" Style="{StaticResource ListLabel}" /> <TextBlock Grid.Row="3" Grid.Column="1" x:Name="txtCount" Style="{StaticResource ListValue}" /> <TextBlock Grid.Row="4" Grid.Column="0" Text="Width:" Style="{StaticResource ListLabel}" /> <TextBlock Grid.Row="4" Grid.Column="1" x:Name="txtWidth" Style="{StaticResource ListValue}" /> </Grid> </Border> </Grid> </Window>
C#
[Main Code]
/// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { #region Contructors /// <summary> /// Main constructor. /// </summary> public MainWindow() { // Initialize UI InitializeComponent(); // Get processor information GetProcessorInformation(); } #endregion /// <summary> /// Retrieve the processor information and add to UI. /// </summary> private void GetProcessorInformation() { // Build an options object for the remote connection var options = new ConnectionOptions { Impersonation = ImpersonationLevel.Impersonate, EnablePrivileges = true }; // Make a connection to a remote computer. var ms = new ManagementScope(@"" + "." + @"rootcimv2", options); // Query string query = "SELECT Manufacturer, MaxClockSpeed, AddressWidth, Name, " + "SocketDesignation, ProcessorID, UniqueID FROM Win32_Processor"; // Searcher var searcher = new ManagementObjectSearcher(ms, new WqlObjectQuery(query)); // Get legacy info var processor = GetProcessorInfoLegacy(searcher); // Processor information // Description txtDescription.Text = RemoveExcessSpaces(processor.Name); if (String.IsNullOrEmpty(txtDescription.Text)) { txtDescription.Text = "{Unknown}"; } // Speed txtSpeed.Text = GetProcessorSpeed(processor.Speed); if (String.IsNullOrEmpty(txtSpeed.Text)) { txtSpeed.Text = "{Unknown}"; } // Count txtCount.Text = GetProcessorCount(5.2, processor); if (String.IsNullOrEmpty(txtCount.Text)) { txtCount.Text = "{Unknown}"; } // Width txtWidth.Text = "x86-" + processor.Architecture; if (String.IsNullOrEmpty(txtWidth.Text)) { txtWidth.Text = "{Unknown}"; } } /// <summary> /// Gets processor information for Windows version 5.x. /// </summary> /// <param name="searcher"></param> /// <returns></returns> private static ProcessorInfo GetProcessorInfoLegacy( ManagementObjectSearcher searcher) { // Processor object var processor = new ProcessorInfo(); // Descriptors var socket = new List<string>(); var procId = new List<string>(); var uniqueId = new List<string>(); // Get data ManagementObjectCollection colItems = searcher.Get(); try { // Evaluate data foreach (ManagementBaseObject objItem in colItems) { // Manufacturer if (objItem["Manufacturer"] != null) { processor.Manufacturer = objItem["Manufacturer"].ToString(); } // Speed if (objItem["MaxClockSpeed"] != null) { processor.Speed = Convert.ToInt32(objItem["MaxClockSpeed"]); } // Architecture if (objItem["AddressWidth"] != null) { processor.Architecture = objItem["AddressWidth"].ToString(); } // Socket Designation if (objItem["SocketDesignation"] != null) { processor.SocketDesignation = objItem["SocketDesignation"].ToString(); socket.Add(processor.SocketDesignation); } // Name if (objItem["Name"] != null) { processor.Name = objItem["Name"].ToString(); } // ProcessorID if (objItem["ProcessorID"] != null) { processor.ProcessorID = objItem["ProcessorID"].ToString(); procId.Add(processor.ProcessorID); } else { procId.Add(""); } // UniqueID if (objItem["UniqueID"] != null) { processor.UniqueID = objItem["UniqueID"].ToString(); uniqueId.Add(processor.UniqueID); } else { uniqueId.Add(""); } } // Logical count int totalProcCount = colItems.Count; processor.LogicalProcessors = totalProcCount; // Cores GetLegacyCoreCount(socket, procId, uniqueId, ref processor); // Get #of possible sockets if ((processor.Cores > 0) && (processor.LogicalProcessors > 0)) { int result = (processor.LogicalProcessors / processor.Cores); processor.Count = result; } } catch { } finally { colItems.Dispose(); } // return return processor; } /// <summary> /// Gets the number of processor cores for Windows version 5.x. /// </summary> /// <param name="socket"></param> /// <param name="procId"></param> /// <param name="uniqueId"></param> /// <param name="processor"></param> private static void GetLegacyCoreCount(List<string> socket, List<string> procId, List<string> uniqueId, ref ProcessorInfo processor) { int totalProcessors = 0; // Processor marker // Check Socket Designation for (int i = 0; i < socket.Count; i++) { // Start with the assumption this is unique. bool isUnique = true; // Check for Redundancies for (int j = i + 1; j < socket.Count; j++) { if (socket[i] == socket[j]) { isUnique = false; break; } } // If Redundant Unique ID's Exist for (int j = i + 1; j < socket.Count; j++) { if ((uniqueId[i] != "") && (uniqueId[j] != "") && (uniqueId[i] != uniqueId[j])) { isUnique = true; break; } } // Check for NULL ProcessorID if (procId[i].Trim() == "0000000000000000") { isUnique = false; } // Calculate Total if (isUnique) { totalProcessors++; } } // Get Cores int result = (processor.LogicalProcessors / totalProcessors); processor.Cores = result; } /// <summary> /// Retrieves the Processor speed in human-readable format. /// </summary> /// <param name="speed"></param> /// <returns></returns> public static string GetProcessorSpeed(int speed) { string result = string.Empty; if (speed.ToString().Length >= 4) { double dSpeed = Convert.ToDouble(speed) / 1000; result = dSpeed.ToString("0.00") + " GHz"; } else { result = speed.ToString() + " MHz"; } // Return return result; } /// <summary> /// Returns the processor count in a human-readable format. /// </summary> /// <param name="oSver"></param> /// <param name="proc"></param> /// <returns></returns> public static string GetProcessorCount(double oSver, ProcessorInfo proc) { string result = ""; int physical = proc.Count; int cores = proc.Cores; // Manufacturer string hyper = "HyperThreading"; if (proc.Manufacturer.ToLower().IndexOf("intel") == -1) { hyper = "HyperTransport"; } // Processor count string physDesc = physical.ToString() + " processor(s)"; // Cores string coreDesc = string.Empty; // Current if (oSver >= 6) { coreDesc = cores.ToString() + " core(s)"; if (proc.IsHyperThreaded) { coreDesc += " w/ HyperThreading"; } } // Legacy else { coreDesc = cores.ToString() + " core(s)"; if ((cores / physical) == 2) { // Intel if (proc.Manufacturer.ToLower().IndexOf("intel") != -1) { coreDesc += " (or " + physical + " core(s) w/ " + hyper + ")"; } } } result = physDesc + " (" + coreDesc + ")"; // Return return result; } /// <summary> /// Removes extra spaces between words. /// </summary> /// <param name="procDesc"></param> /// <returns></returns> public static string RemoveExcessSpaces(string procDesc) { string result = ""; // Evaluate string[] desc = procDesc.Split((char)32); // Name for (int i = 0; i < desc.Length; i++) { if (desc[i].Trim() != "") { result += desc[i] + " "; } } // Return return result; } }
[ProcessorInfo class]
/// <summary> /// Information relevant to the physical processors. /// </summary> public class ProcessorInfo { #region Properties /// <summary> /// Win32_Processor: AddressWidth: On a 32-bit operating system, the value is 32 /// and on a 64-bit operating system it is 64. /// </summary> public string Architecture { get; set; } /// <summary> /// Win32_Processor: NumberOfCores: Number of cores for the current instance of /// the processor. /// </summary> public int Cores { get; set; } /// <summary> /// Total processor count. /// </summary> public int Count { get; set; } /// <summary> /// Determines whether processors support Hyper-Threading or Hyper-Transport. /// </summary> public bool IsHyperThreaded { get; set; } /// <summary> /// Win32_Processor: NumberOfLogicalProcessors: Number of logical processors for /// the current instance of the processor. /// </summary> public int LogicalProcessors { get; set; } /// <summary> /// Win32_Processor: Manufacturer: Name of the processor manufacturer. /// </summary> public string Manufacturer { get; set; } /// <summary> /// Win32_Processor: Name: Label by which the object is known. /// </summary> public string Name { get; set; } /// <summary> /// Win32_Processor: ProcessorID: Processor information that describes the /// processor features. /// </summary> public string ProcessorID { get; set; } /// <summary> /// Win32_Processor: SocketDesignation: Type of chip socket used on the circuit. /// </summary> public string SocketDesignation { get; set; } /// <summary> /// Win32_Processor: MaxClockSpeed: Detected processor speed. /// </summary> public int Speed { get; set; } /// <summary> /// Win32_Processor: UniqueID: Globally unique identifier for the processor. /// </summary> public string UniqueID { get; set; } #endregion #region Constructors public ProcessorInfo() { Architecture = "x86"; } #endregion }