Answered by:
PerformanceCounter category doesn't exist on a few PC's!

Question
-
Hi!
I'm working on a little CPU monitoring tool, that shows also the current CPU clock. So what he needs is a PerformanceCounter from the category Processorinformation -> % Processorspeed (I don't know how it calls on english because I'm german :p). Alright... on my PC with Windows 8.1 it works perfect. But on a few PC they have also Windows 8.1 or Windows 7, they got this error: http://i.imgur.com/ofeyXn4.jpg
Can some help me?
Greetings
Christian/DeDelner- Edited by Christian,DeDelner Sunday, November 2, 2014 12:37 AM
Sunday, November 2, 2014 12:33 AM
Answers
-
Well I also found some information from this link PerformanceCounterCategory Class.
"It is strongly recommended that new performance counter categories be created during the installation of the application, not during the execution of the application. This allows time for the operating system to refresh its list of registered performance counter categories. If the list has not been refreshed, the attempt to use the category will fail."
And
"The following code example determines whether a PerformanceCounter and its PerformanceCounterCategory exist on the local computer or on another computer. If these objects do not exist on the local computer, the example optionally creates them. It uses the Exists method to determine whether the PerformanceCounterCategory exists. If the PerformanceCounterCategory does not exist and no counter name is specified, or if the computer is a remote machine, the example exits.
If a PerformanceCounter name is provided, the example uses the CounterExists method and displays the result to the user. If the PerformanceCounterdoes not exist, the user can delete and re-create the PerformanceCounterCategorywith the new PerformanceCounter. If the user does so, the category is deleted using the Delete method.
If requested, the example now creates the new PerformanceCounterCategory and PerformanceCounter using the Create method. If an instance name is specified, the example uses the InstanceExists method and displays the result."
La vida loca
- Proposed as answer by Cor Ligthert Tuesday, November 4, 2014 7:18 AM
- Marked as answer by Carl Cai Wednesday, November 19, 2014 8:06 AM
Tuesday, November 4, 2014 3:17 AM -
You could try this code. Which should get a list of all performance counter categories on a machine into ListBox1 by selecting Button1.
Then you select one of the entries in ListBox1 and select Button2. This will get a list of all performance counter instance names for the performance counter category selected in ListBox1.
Then select one of the entries in ListBox2 and select Button3. ListBox3 will display a list of performance counters available for the performance counter instance name selected in ListBox2.
Then select one of the performance counters in ListBox3 and start the timer.
If a category, instance name or performance counter is not available on the machine the program is run on then it will not be displayed. I could not find a performance counter called "ProcessorSpeed" for my machine though.
Also in my next post I will provide the Form1.Designer.vb code so if you want to create this app you should be able to use that code to provide all the controls on a blank Form and the below code copied over any code in Form1.vb.
Option Strict On Public Class Form1 'Code used is from below two links. ' 'Walkthrough: Retrieving Categories and Counters 'http://msdn.microsoft.com/en-us/library/2fh4x1xb(v=vs.90).aspx ' 'A Quick Introduction to Performance Counters in Visual Studio 2012 'http://www.codeguru.com/columns/vb/a-quick-introduction-to-performance-counters-in-visual-studio-2012.htm Private pc As PerformanceCounter Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.CenterToScreen() Me.Text = "Performance Counters" ListBox1.Sorted = True ListBox2.Sorted = True ListBox3.Sorted = True Button4.BackColor = Color.Lime Button4.Text = "Start Timer" Timer1.Interval = 1000 End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim myCat As PerformanceCounterCategory() Dim i As Integer ListBox1.Items.Clear() myCat = PerformanceCounterCategory.GetCategories For i = 0 To myCat.Length - 1 ListBox1.Items.Add(myCat(i).CategoryName) Next End Sub Dim InstanceNames() As String Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click ListBox2.Items.Clear() If ListBox1.SelectedIndex <> -1 Then Dim mycat As New PerformanceCounterCategory(ListBox1.SelectedItem.ToString()) InstanceNames = mycat.GetInstanceNames() If InstanceNames.Count > 0 Then For Each Item In InstanceNames ListBox2.Items.Add(Item) Next End If End If End Sub Dim Counters As New System.Collections.ArrayList Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click ListBox3.Items.Clear() Counters.Clear() If ListBox1.SelectedIndex <> -1 And ListBox2.SelectedIndex <> -1 Then Dim mycat As New PerformanceCounterCategory(ListBox1.SelectedItem.ToString()) Counters.AddRange(mycat.GetCounters(ListBox2.SelectedItem.ToString)) Dim counter As PerformanceCounter For Each counter In Counters ListBox3.Items.Add(counter.CounterName) Next End If End Sub Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click If Button4.Text = "Start Timer" Then Button4.BackColor = Color.OrangeRed Button4.Text = "Stop Timer" Timer1.Start() Else Button4.BackColor = Color.Lime Button4.Text = "Start Timer" Timer1.Stop() End If End Sub Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick RichTextBox1.Text = "" If ListBox1.SelectedIndex <> -1 And ListBox2.SelectedIndex <> -1 And ListBox3.SelectedIndex <> -1 Then pc = New PerformanceCounter() pc.CategoryName = ListBox1.SelectedItem.ToString pc.InstanceName = ListBox2.SelectedItem.ToString pc.CounterName = ListBox3.SelectedItem.ToString RichTextBox1.AppendText(pc.CounterHelp.ToString & vbCrLf & vbCrLf & vbCrLf & "RawValue = " & pc.RawValue.ToString & vbCrLf & "NextValue = " & pc.NextValue.ToString) End If End Sub End Class
La vida loca
- Proposed as answer by Cor Ligthert Tuesday, November 4, 2014 7:17 AM
- Marked as answer by Carl Cai Wednesday, November 19, 2014 8:06 AM
Sunday, November 2, 2014 10:52 PM -
The OS language is very likely the culprit here, because performance counters are intended for use/browsing via the MMC snap-in so their names will probably assume the language of the OS locale.
You may want to investigate WMI instead, it should get you what you need (and be language independent):
- Marked as answer by Carl Cai Wednesday, November 19, 2014 8:06 AM
Wednesday, November 5, 2014 1:35 PM -
You can download Microsofts WMI Code Creator v1.0 which can created code in VB.Net, VB.Script or C#. It executes the created code in Console Apps though so the code is written to be used that way. Below is an image but I don't know how to use it to create a performance counter. Maybe under "execute a method".
Maybe this article from Code Project can give you insight on how to create a performance counter as it seem fairly well written - An Introduction To Performance Counters
La vida loca
- Marked as answer by Carl Cai Wednesday, November 19, 2014 8:06 AM
Wednesday, November 5, 2014 3:08 PM
All replies
-
Hi!
I'm working on a little CPU monitoring tool, that shows also the current CPU clock. So what he needs is a PerformanceCounter from the category Processorinformation -> % Processorspeed (I don't know how it calls on english because I'm german :p). Alright... on my PC with Windows 8.1 it works perfect. But on a few PC they have also Windows 8.1 or Windows 7, they got this error: http://i.imgur.com/ofeyXn4.jpg
Can some help me?
Greetings
Christian/DeDelner
You mention that this application works fine on your PC.
I would guess your PC is also the PC that the application was created on using Visual Studio. Is that correct?
You don't say if your application works on any other PC.
You do say that your application does not work on a few other PC's that have Windows 8.1 or Windows 7 operating systems. Which normally would mean it works on other Windows 8.1 or Windows 7 PC's just not a few of them. Is this correct?
La vida loca
Sunday, November 2, 2014 10:27 PM -
You could try this code. Which should get a list of all performance counter categories on a machine into ListBox1 by selecting Button1.
Then you select one of the entries in ListBox1 and select Button2. This will get a list of all performance counter instance names for the performance counter category selected in ListBox1.
Then select one of the entries in ListBox2 and select Button3. ListBox3 will display a list of performance counters available for the performance counter instance name selected in ListBox2.
Then select one of the performance counters in ListBox3 and start the timer.
If a category, instance name or performance counter is not available on the machine the program is run on then it will not be displayed. I could not find a performance counter called "ProcessorSpeed" for my machine though.
Also in my next post I will provide the Form1.Designer.vb code so if you want to create this app you should be able to use that code to provide all the controls on a blank Form and the below code copied over any code in Form1.vb.
Option Strict On Public Class Form1 'Code used is from below two links. ' 'Walkthrough: Retrieving Categories and Counters 'http://msdn.microsoft.com/en-us/library/2fh4x1xb(v=vs.90).aspx ' 'A Quick Introduction to Performance Counters in Visual Studio 2012 'http://www.codeguru.com/columns/vb/a-quick-introduction-to-performance-counters-in-visual-studio-2012.htm Private pc As PerformanceCounter Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Me.CenterToScreen() Me.Text = "Performance Counters" ListBox1.Sorted = True ListBox2.Sorted = True ListBox3.Sorted = True Button4.BackColor = Color.Lime Button4.Text = "Start Timer" Timer1.Interval = 1000 End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim myCat As PerformanceCounterCategory() Dim i As Integer ListBox1.Items.Clear() myCat = PerformanceCounterCategory.GetCategories For i = 0 To myCat.Length - 1 ListBox1.Items.Add(myCat(i).CategoryName) Next End Sub Dim InstanceNames() As String Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click ListBox2.Items.Clear() If ListBox1.SelectedIndex <> -1 Then Dim mycat As New PerformanceCounterCategory(ListBox1.SelectedItem.ToString()) InstanceNames = mycat.GetInstanceNames() If InstanceNames.Count > 0 Then For Each Item In InstanceNames ListBox2.Items.Add(Item) Next End If End If End Sub Dim Counters As New System.Collections.ArrayList Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click ListBox3.Items.Clear() Counters.Clear() If ListBox1.SelectedIndex <> -1 And ListBox2.SelectedIndex <> -1 Then Dim mycat As New PerformanceCounterCategory(ListBox1.SelectedItem.ToString()) Counters.AddRange(mycat.GetCounters(ListBox2.SelectedItem.ToString)) Dim counter As PerformanceCounter For Each counter In Counters ListBox3.Items.Add(counter.CounterName) Next End If End Sub Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click If Button4.Text = "Start Timer" Then Button4.BackColor = Color.OrangeRed Button4.Text = "Stop Timer" Timer1.Start() Else Button4.BackColor = Color.Lime Button4.Text = "Start Timer" Timer1.Stop() End If End Sub Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick RichTextBox1.Text = "" If ListBox1.SelectedIndex <> -1 And ListBox2.SelectedIndex <> -1 And ListBox3.SelectedIndex <> -1 Then pc = New PerformanceCounter() pc.CategoryName = ListBox1.SelectedItem.ToString pc.InstanceName = ListBox2.SelectedItem.ToString pc.CounterName = ListBox3.SelectedItem.ToString RichTextBox1.AppendText(pc.CounterHelp.ToString & vbCrLf & vbCrLf & vbCrLf & "RawValue = " & pc.RawValue.ToString & vbCrLf & "NextValue = " & pc.NextValue.ToString) End If End Sub End Class
La vida loca
- Proposed as answer by Cor Ligthert Tuesday, November 4, 2014 7:17 AM
- Marked as answer by Carl Cai Wednesday, November 19, 2014 8:06 AM
Sunday, November 2, 2014 10:52 PM -
If you want to create this app start a new Visual Basic windows forms app. Once you have a Form displayed in the designer window then in Solution Explorer click on the "display all files" square button.
Then look down the list in Solution Explorer and where Form1 is with a little black triangle pointing towards it click on the little black triangle which should then angle down and some filenames should be displayed under Form1.
Select the Form1.Designer.vb file so you can view its code. Once that code window opens copy and paste the below code over any code in that window. As soon as you do that the Form should resized and have all the controls on it as well as a Timer at the bottom of the window.
Then open Form1's code window and copy/paste the code from my previous post over any code in that window.
You should then be able to build the project and it should be ready to run.
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _ Partial Class Form1 Inherits System.Windows.Forms.Form 'Form overrides dispose to clean up the component list. <System.Diagnostics.DebuggerNonUserCode()> _ Protected Overrides Sub Dispose(ByVal disposing As Boolean) Try If disposing AndAlso components IsNot Nothing Then components.Dispose() End If Finally MyBase.Dispose(disposing) End Try End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> _ Private Sub InitializeComponent() Me.components = New System.ComponentModel.Container() Me.Button1 = New System.Windows.Forms.Button() Me.Button2 = New System.Windows.Forms.Button() Me.ListBox1 = New System.Windows.Forms.ListBox() Me.ListBox2 = New System.Windows.Forms.ListBox() Me.Label1 = New System.Windows.Forms.Label() Me.Label2 = New System.Windows.Forms.Label() Me.Label3 = New System.Windows.Forms.Label() Me.RichTextBox1 = New System.Windows.Forms.RichTextBox() Me.Timer1 = New System.Windows.Forms.Timer(Me.components) Me.Button3 = New System.Windows.Forms.Button() Me.ListBox3 = New System.Windows.Forms.ListBox() Me.Button4 = New System.Windows.Forms.Button() Me.Label4 = New System.Windows.Forms.Label() Me.SuspendLayout() ' 'Button1 ' Me.Button1.Location = New System.Drawing.Point(2, 3) Me.Button1.Name = "Button1" Me.Button1.Size = New System.Drawing.Size(95, 23) Me.Button1.TabIndex = 0 Me.Button1.Text = "Get Categories" Me.Button1.UseVisualStyleBackColor = True ' 'Button2 ' Me.Button2.Location = New System.Drawing.Point(310, 6) Me.Button2.Name = "Button2" Me.Button2.Size = New System.Drawing.Size(169, 23) Me.Button2.TabIndex = 1 Me.Button2.Text = "Get a categories Instance names" Me.Button2.UseVisualStyleBackColor = True ' 'ListBox1 ' Me.ListBox1.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.ListBox1.FormattingEnabled = True Me.ListBox1.ItemHeight = 20 Me.ListBox1.Location = New System.Drawing.Point(1, 63) Me.ListBox1.Name = "ListBox1" Me.ListBox1.ScrollAlwaysVisible = True Me.ListBox1.Size = New System.Drawing.Size(264, 184) Me.ListBox1.TabIndex = 2 ' 'ListBox2 ' Me.ListBox2.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.ListBox2.FormattingEnabled = True Me.ListBox2.ItemHeight = 20 Me.ListBox2.Location = New System.Drawing.Point(275, 63) Me.ListBox2.Name = "ListBox2" Me.ListBox2.ScrollAlwaysVisible = True Me.ListBox2.Size = New System.Drawing.Size(264, 184) Me.ListBox2.TabIndex = 3 ' 'Label1 ' Me.Label1.AutoSize = True Me.Label1.BackColor = System.Drawing.Color.WhiteSmoke Me.Label1.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.Label1.Location = New System.Drawing.Point(104, 5) Me.Label1.Name = "Label1" Me.Label1.Size = New System.Drawing.Size(194, 20) Me.Label1.TabIndex = 4 Me.Label1.Text = "PC Performance Counters" ' 'Label2 ' Me.Label2.AutoSize = True Me.Label2.BackColor = System.Drawing.Color.PapayaWhip Me.Label2.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.Label2.Location = New System.Drawing.Point(77, 37) Me.Label2.Name = "Label2" Me.Label2.Size = New System.Drawing.Size(102, 20) Me.Label2.TabIndex = 5 Me.Label2.Text = "Category List" ' 'Label3 ' Me.Label3.AutoSize = True Me.Label3.BackColor = System.Drawing.Color.PapayaWhip Me.Label3.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.Label3.Location = New System.Drawing.Point(631, 39) Me.Label3.Name = "Label3" Me.Label3.Size = New System.Drawing.Size(95, 20) Me.Label3.TabIndex = 6 Me.Label3.Text = "Counter List" ' 'RichTextBox1 ' Me.RichTextBox1.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.RichTextBox1.Location = New System.Drawing.Point(2, 279) Me.RichTextBox1.Name = "RichTextBox1" Me.RichTextBox1.Size = New System.Drawing.Size(1024, 316) Me.RichTextBox1.TabIndex = 7 Me.RichTextBox1.Text = "" ' 'Timer1 ' ' 'Button3 ' Me.Button3.Location = New System.Drawing.Point(595, 6) Me.Button3.Name = "Button3" Me.Button3.Size = New System.Drawing.Size(175, 23) Me.Button3.TabIndex = 8 Me.Button3.Text = "Get Counters for an Instance" Me.Button3.UseVisualStyleBackColor = True ' 'ListBox3 ' Me.ListBox3.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.ListBox3.FormattingEnabled = True Me.ListBox3.ItemHeight = 20 Me.ListBox3.Location = New System.Drawing.Point(549, 64) Me.ListBox3.Name = "ListBox3" Me.ListBox3.ScrollAlwaysVisible = True Me.ListBox3.Size = New System.Drawing.Size(478, 184) Me.ListBox3.TabIndex = 9 ' 'Button4 ' Me.Button4.Location = New System.Drawing.Point(4, 252) Me.Button4.Name = "Button4" Me.Button4.Size = New System.Drawing.Size(85, 23) Me.Button4.TabIndex = 10 Me.Button4.Text = "Start Timer" Me.Button4.UseVisualStyleBackColor = True ' 'Label4 ' Me.Label4.AutoSize = True Me.Label4.BackColor = System.Drawing.Color.PapayaWhip Me.Label4.Font = New System.Drawing.Font("Microsoft Sans Serif", 12.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte)) Me.Label4.Location = New System.Drawing.Point(290, 40) Me.Label4.Name = "Label4" Me.Label4.Size = New System.Drawing.Size(217, 20) Me.Label4.TabIndex = 11 Me.Label4.Text = "A Categories instance names" ' 'Form1 ' Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!) Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font Me.ClientSize = New System.Drawing.Size(1033, 603) Me.Controls.Add(Me.Label4) Me.Controls.Add(Me.Button4) Me.Controls.Add(Me.ListBox3) Me.Controls.Add(Me.Button3) Me.Controls.Add(Me.RichTextBox1) Me.Controls.Add(Me.Label3) Me.Controls.Add(Me.Label2) Me.Controls.Add(Me.Label1) Me.Controls.Add(Me.ListBox2) Me.Controls.Add(Me.ListBox1) Me.Controls.Add(Me.Button2) Me.Controls.Add(Me.Button1) Me.Name = "Form1" Me.Text = "Form1" Me.ResumeLayout(False) Me.PerformLayout() End Sub Friend WithEvents Button1 As System.Windows.Forms.Button Friend WithEvents Button2 As System.Windows.Forms.Button Friend WithEvents ListBox1 As System.Windows.Forms.ListBox Friend WithEvents ListBox2 As System.Windows.Forms.ListBox Friend WithEvents Label1 As System.Windows.Forms.Label Friend WithEvents Label2 As System.Windows.Forms.Label Friend WithEvents Label3 As System.Windows.Forms.Label Friend WithEvents RichTextBox1 As System.Windows.Forms.RichTextBox Friend WithEvents Timer1 As System.Windows.Forms.Timer Friend WithEvents Button3 As System.Windows.Forms.Button Friend WithEvents ListBox3 As System.Windows.Forms.ListBox Friend WithEvents Button4 As System.Windows.Forms.Button Friend WithEvents Label4 As System.Windows.Forms.Label End Class
La vida loca
Sunday, November 2, 2014 10:58 PM -
Well I also found some information from this link PerformanceCounterCategory Class.
"It is strongly recommended that new performance counter categories be created during the installation of the application, not during the execution of the application. This allows time for the operating system to refresh its list of registered performance counter categories. If the list has not been refreshed, the attempt to use the category will fail."
And
"The following code example determines whether a PerformanceCounter and its PerformanceCounterCategory exist on the local computer or on another computer. If these objects do not exist on the local computer, the example optionally creates them. It uses the Exists method to determine whether the PerformanceCounterCategory exists. If the PerformanceCounterCategory does not exist and no counter name is specified, or if the computer is a remote machine, the example exits.
If a PerformanceCounter name is provided, the example uses the CounterExists method and displays the result to the user. If the PerformanceCounterdoes not exist, the user can delete and re-create the PerformanceCounterCategorywith the new PerformanceCounter. If the user does so, the category is deleted using the Delete method.
If requested, the example now creates the new PerformanceCounterCategory and PerformanceCounter using the Create method. If an instance name is specified, the example uses the InstanceExists method and displays the result."
La vida loca
- Proposed as answer by Cor Ligthert Tuesday, November 4, 2014 7:18 AM
- Marked as answer by Carl Cai Wednesday, November 19, 2014 8:06 AM
Tuesday, November 4, 2014 3:17 AM -
Well, I was wondering if it has something to do with the current language on the PC. And then, how I create simply a new PerformanceCounter/Category? I need a PerformanceCounter that can read the current CPU clock in %.Wednesday, November 5, 2014 11:42 AM
-
The OS language is very likely the culprit here, because performance counters are intended for use/browsing via the MMC snap-in so their names will probably assume the language of the OS locale.
You may want to investigate WMI instead, it should get you what you need (and be language independent):
- Marked as answer by Carl Cai Wednesday, November 19, 2014 8:06 AM
Wednesday, November 5, 2014 1:35 PM -
You can download Microsofts WMI Code Creator v1.0 which can created code in VB.Net, VB.Script or C#. It executes the created code in Console Apps though so the code is written to be used that way. Below is an image but I don't know how to use it to create a performance counter. Maybe under "execute a method".
Maybe this article from Code Project can give you insight on how to create a performance counter as it seem fairly well written - An Introduction To Performance Counters
La vida loca
- Marked as answer by Carl Cai Wednesday, November 19, 2014 8:06 AM
Wednesday, November 5, 2014 3:08 PM