All posts tagged xaml

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<Window x:Class="GetProcessCountLegacy.MainWindow"
        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]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/// <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]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/// <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
}