-
Apr 18th, 2013, 10:15 AM
#1
Thread Starter
Junior Member
Cpu Utilization in vb6
Code:
Private Wmi As Object, Locator As Object
Private PrevCpuTime As Long, SampleRate As Long
Private Sub Form_Load()
SampleRate = 2 'in seconds
Timer1.Interval = SampleRate * 1000
Set Locator = CreateObject("WbemScripting.SWbemLocator")
Set Wmi = Locator.ConnectServer
Timer1_Timer
End Sub
Private Sub Timer1_Timer()
Dim Procs As Object, Proc As Object
Dim CpuTime, Utilization As Single
Set Procs = Wmi.InstancesOf("Win32_Process")
For Each Proc In Procs
If Proc.ProcessID = 0 Then 'System Idle Process
CpuTime = Proc.KernelModeTime / 10000000
If PrevCpuTime <> 0 Then
Utilization = 1 - (CpuTime - PrevCpuTime) / SampleRate
Text1.Text = Format(Utilization, "0.0%")
End If
PrevCpuTime = CpuTime
End If
Next
End Sub
-
Apr 18th, 2013, 11:13 AM
#2
Re: Cpu Utilization in vb6
When compared against Task Manager, the average values are oftentimes in disagreement. In fact, negative percentages are sometimes displayed. BTW, CpuTime was implicitly declared as a Variant.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Apr 18th, 2013, 01:07 PM
#3
Re: Cpu Utilization in vb6
Moved to the VB6 CodeBank.
Originally Posted by Bonnie West
When compared against Task Manager, the average values are oftentimes in disagreement. In fact, negative percentages are sometimes displayed. BTW, CpuTime was implicitly declared as a Variant.
That's because the code is completely wrong. What it tries to do is to get the CPU usage information from each running process, but it updates the information inside the loop.
Say you have 96 running processes (which is what I currently have with all services and apps that runs) then the For Each loop will loop 96 times, but it updates the textbox inside the loop and the only one you will see is the last one, where the PrevCpuTime is set to .... well, who knows? It will be something like the KernelModeTime used by the earlier process, which is not even of interest.
To get the CPU usage you shouldn't go through the running processes, instead you should get the processor information (as opposed to process information), since modern day computers have more processor cores you have to add them up and then to get an average divide the result with the number of processors in your computer (this isn't perfect since you get an average, but it's close enough).
Code:
Private wmi As Object
Private Sub Form_Load()
Me.Show
Set wmi = GetObject("winmgmts:\\.\root\CIMV2")
Timer1.Interval = 1000
Timer1_Timer
End Sub
Private Sub Timer1_Timer()
Dim query As Object, counter As Object
Dim percent As Double
Set query = wmi.ExecQuery("SELECT * FROM Win32_PerfFormattedData_Counters_ProcessorInformation")
For Each counter In query
percent = percent + counter.PercentProcessorTime
Next
Text1.Text = Format(percent / query.Count, "0.00") & "%"
End Sub
Last edited by Joacim Andersson; Apr 18th, 2013 at 01:51 PM.
-
Apr 21st, 2013, 02:37 AM
#4
Thread Starter
Junior Member
Re: Cpu Utilization in vb6
Originally Posted by Joacim Andersson
Moved to the VB6 CodeBank.
That's because the code is completely wrong. What it tries to do is to get the CPU usage information from each running process, but it updates the information inside the loop.
Say you have 96 running processes (which is what I currently have with all services and apps that runs) then the For Each loop will loop 96 times, but it updates the textbox inside the loop and the only one you will see is the last one, where the PrevCpuTime is set to .... well, who knows? It will be something like the KernelModeTime used by the earlier process, which is not even of interest.
To get the CPU usage you shouldn't go through the running processes, instead you should get the processor information (as opposed to process information), since modern day computers have more processor cores you have to add them up and then to get an average divide the result with the number of processors in your computer (this isn't perfect since you get an average, but it's close enough).
Code:
Private wmi As Object
Private Sub Form_Load()
Me.Show
Set wmi = GetObject("winmgmts:\\.\root\CIMV2")
Timer1.Interval = 1000
Timer1_Timer
End Sub
Private Sub Timer1_Timer()
Dim query As Object, counter As Object
Dim percent As Double
Set query = wmi.ExecQuery("SELECT * FROM Win32_PerfFormattedData_Counters_ProcessorInformation")
For Each counter In query
percent = percent + counter.PercentProcessorTime
Next
Text1.Text = Format(percent / query.Count, "0.00") & "%"
End Sub
your code isnt working and it opens some switch mode
-
Apr 21st, 2013, 04:10 AM
#5
Re: Cpu Utilization in vb6
What do you mean with "switch mode". It's working perfectly well on my machine. What Windows version are you using?
-
Apr 21st, 2013, 04:35 AM
#6
Re: Cpu Utilization in vb6
@JA
I receive an automation error on this line
vb Code:
For Each counter In query
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Apr 21st, 2013, 04:51 AM
#7
Re: Cpu Utilization in vb6
Tried it again, works fine for me. What Windows version are you running? Try running it with elevated privileges.
-
Apr 21st, 2013, 05:06 AM
#8
Re: Cpu Utilization in vb6
I'm running the code in an elevated IDE under Window 7 Home.
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Apr 21st, 2013, 05:17 AM
#9
Re: Cpu Utilization in vb6
I'm not sure but it might be some required service that's not started by default on home edition. I've executed this on both Win7 and Win8 and it works fine.
-
Apr 21st, 2013, 05:29 AM
#10
Re: Cpu Utilization in vb6
Suppose I could try it on my Windows 7 Professional laptop and see how it runs.
when you quote a post could you please do it via the "Reply With Quote" button or if it multiple post click the "''+" button then "Reply With Quote" button.
If this thread is finished with please mark it "Resolved" by selecting "Mark thread resolved" from the "Thread tools" drop-down menu.
https://get.cryptobrowser.site/30/4111672
-
Apr 21st, 2013, 08:59 AM
#11
Re: Cpu Utilization in vb6
I get the same error on the For Each line as well (on XP). Specifically, the error was wbemErrInvalidClass (0x80041010) - The specified class is not valid. The value for query's Count property was <Invalid class>.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Apr 21st, 2013, 10:46 AM
#12
Re: Cpu Utilization in vb6
Try this instead and see if you can get it to work.
Code:
Private wmi As Object
Private Sub Form_Load()
Me.Show
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Timer1.Interval = 1000
Timer1_Timer
End Sub
Private Sub Timer1_Timer()
Dim query As Object, counter As Object
Dim percent As Double
Set query = wmi.ExecQuery("Select * from Win32_Processor")
For Each counter In query
percent = percent + counter.LoadPercentage
Next
Text1.Text = Format(percent / query.Count, "0.00") & "%"
End Sub
-
Apr 21st, 2013, 11:07 AM
#13
Re: Cpu Utilization in vb6
Originally Posted by Joacim Andersson
Try this instead and see if you can get it to work.
Well, now I get Error 94 - Invalid use of Null. counter.LoadPercentage returns Variant/Null.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Apr 21st, 2013, 12:17 PM
#14
Re: Cpu Utilization in vb6
Well, there's obviously something missing for you to run WMI queries. I'm no expert in that area but both scripts works fine for me.
-
Apr 21st, 2013, 12:42 PM
#15
Re: Cpu Utilization in vb6
Originally Posted by Joacim Andersson
Moved to the VB6 CodeBank.
That's because the code is completely wrong. What it tries to do is to get the CPU usage information from each running process, but it updates the information inside the loop.
Say you have 96 running processes (which is what I currently have with all services and apps that runs) then the For Each loop will loop 96 times, but it updates the textbox inside the loop and the only one you will see is the last one, where the PrevCpuTime is set to .... well, who knows? It will be something like the KernelModeTime used by the earlier process, which is not even of interest.
To get the CPU usage you shouldn't go through the running processes, instead you should get the processor information (as opposed to process information), since modern day computers have more processor cores you have to add them up and then to get an average divide the result with the number of processors in your computer (this isn't perfect since you get an average, but it's close enough).
Code:
Private wmi As Object
Private Sub Form_Load()
Me.Show
Set wmi = GetObject("winmgmts:\\.\root\CIMV2")
Timer1.Interval = 1000
Timer1_Timer
End Sub
Private Sub Timer1_Timer()
Dim query As Object, counter As Object
Dim percent As Double
Set query = wmi.ExecQuery("SELECT * FROM Win32_PerfFormattedData_Counters_ProcessorInformation")
For Each counter In query
percent = percent + counter.PercentProcessorTime
Next
Text1.Text = Format(percent / query.Count, "0.00") & "%"
End Sub
Works for me I'm on Windows 7 Home Premium.
Copy - Paste, added Timer1 and Text1.
-
Apr 28th, 2013, 04:10 AM
#16
Re: Cpu Utilization in vb6
Using my WMI Browser (http://www.vbforums.com/showthread.p...ser&highlight=) on a Dual Core, 4 Logical Processor machine the _ProcessorInformation query returns 6 records:
Record 1 'Name' Property = _Total
Record 2 'Name' Property = 0,_Total
Record 3 'Name' Property = 0,3
Record 4 'Name' Property = 0,2
Record 5 'Name' Property = 0,1
Record 6 'Name 'Property = 0,0
I'd guess that only record 1 (or perhaps 2) are actually required. Adding all 6 up and taking the average will not be correct (if I interpret MS's use of the word "Total" correctly)
Just for fun, I tried 4 methods and unsurprisingly, got 4 different results.
Code:
Private wmi As Object
Private Sub Form_Load()
Me.Show
Set wmi = GetObject("winmgmts:\\.\root\CIMV2")
Timer1.Interval = 500
Timer1_Timer
End Sub
Private Sub Timer1_Timer()
Dim query As Object, query1 As Object, counter As Object
Dim percent As Double
Set query = wmi.ExecQuery("SELECT * FROM Win32_PerfFormattedData_Counters_ProcessorInformation")
Set query1 = wmi.ExecQuery("Select * from Win32_Processor")
For Each counter In query
Select Case counter.Name
Case "_Total"
Text1.Text = "_Total: " & Format(counter.percentprocessortime, "0.00") & "%"
Case "0,_Total"
Text2.Text = "0,_Total: " & Format(counter.percentprocessortime, "0.00") & "%"
Case Else
percent = percent + counter.percentprocessortime
End Select
Next
Text3.Text = "Average of " & CStr(query.Count) & " records: " & Format(percent / query.Count, "0.00") & "%"
percent = 0
For Each counter In query1
percent = percent + counter.LoadPercentage
Text4.Text = "LoadPercentage(" & counter.numberoflogicalprocessors & "LPs): " & Format(percent, "0.00") & "%"
Next
End Sub
@Bonnie: You may like to run the WMI Browser and see if you can find (in the CIMV2 Namespace) the Classes. I know that some classes have been 'moved about' by MS with various Versions of Windows.
You should find the Win32_Processor class in:
CIM_Managed_System_Element -> CIM_LogicalDevice -> CIM_Processor
The LoadPercentage property is an unsigned 16 bit integer.
The Win32_PerfFormattedData_Counters_ProcessorInformation class should be found in
CIM_StatisticalInformation -> Win32_Perf -> Win32_PerfFormattedData
-
Apr 28th, 2013, 12:09 PM
#17
Re: Cpu Utilization in vb6
Originally Posted by Doogle
@Bonnie: You may like to run the WMI Browser and see if you can find (in the CIMV2 Namespace) the Classes. I know that some classes have been 'moved about' by MS with various Versions of Windows.
You should find the Win32_Processor class in:
CIM_Managed_System_Element -> CIM_LogicalDevice -> CIM_Processor
The LoadPercentage property is an unsigned 16 bit integer.
The Win32_PerfFormattedData_Counters_ProcessorInformation class should be found in
CIM_StatisticalInformation -> Win32_Perf -> Win32_PerfFormattedData
I only had a quick look, but unfortunately, I couldn't find both classes in those locations. I didn't try searching further because I was overwhelmed by the number of available classes. Thanks anyway!
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
-
Jul 10th, 2021, 02:02 PM
#18
Member
Re: Cpu Utilization in vb6
I took Doogle's code and made it so you can query a specific property
Code:
Private WMI As Object
'CPU or Core: -1=total of all CPU/Core values, 0 or above=that specific CPU/core value (value = percent processor time)
'CPU: -2=total # of cores, -3=average of all cores, -4=average Load percentage of all CPUs, -5=summary (text), -6=CSV of all core values
Public Function CPU_Usage(Optional CPU As Long = -1, Optional Core As Long = -1) As String
Dim query As Object, query1 As Object, counter As Object, percent As Double, Cores As String, Value As String, Count As Long, Index As Long, Total As String
If WMI Is Nothing Then Set WMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set query = WMI.ExecQuery("SELECT * FROM Win32_PerfFormattedData_Counters_ProcessorInformation")
Set query1 = WMI.ExecQuery("Select * from Win32_Processor")
For Each counter In query
Value = Format(counter.percentprocessortime, "0.00")
If CPU = -5 Then Total = Append(Total, counter.Name & "=" & Value, vbNewLine)
If counter.Name = "_Total" Then 'total of all CPUs
If CPU = -1 And Core = -1 Then CPU_Usage = Value
ElseIf EndsWith(counter.Name, ",_Total") Then ' counter.Name = CPU & ",_Total" Then
Index = Val(Replace(counter.Name, ",_Total", ""))
If Core = -1 Then CPU_Usage = Value
Else
Cores = Append(Cores, Value, ",")
percent = percent + counter.percentprocessortime
Count = Count + 1
If CPU = Index And Core = counter.Name Then CPU_Usage = Value
End If
Next
Select Case CPU
Case -2: CPU_Usage = Count 'total number of cores
Case -3: CPU_Usage = Format(percent / Count, "0.00") 'average of all cores
Case Else
If Core < -1 Or CPU < 0 Then
If CPU = -5 Then Total = Append(Total, ",_avg=" & Format(percent / Count, "0.00"), vbNewLine)
percent = 0
Index = 0
For Each counter In query1
Value = Format(counter.LoadPercentage, "0.00")
If CPU = -5 Then Total = Append(Total, Index & ",Load=" & Value & vbNewLine & Index & ",Cores=" & counter.numberoflogicalprocessors, vbNewLine)
percent = percent + counter.LoadPercentage
If CPU = Index Then
Select Case Core
Case -2: CPU_Usage = counter.numberoflogicalprocessors 'number of cores
Case -3: CPU_Usage = Value 'load percentage
End Select
End If
Index = Index + 1
Next
Select Case CPU
Case -4: CPU_Usage = Format(percent / Index, "0.00")
Case -5: CPU_Usage = Total & vbNewLine & ",_Cores=" & Count
Case -6: CPU_Usage = Cores 'CSV
End Select
End If
End Select
End Function
-
Jul 13th, 2021, 06:25 PM
#19
Hyperactive Member
Re: Cpu Utilization in vb6
Code:
If CPU = -5 Then Total = Append(Total, counter.Name & "=" & Value, vbNewLine)
"Append" is not a valid function in VB6 or VBA...
-
Jul 14th, 2021, 07:49 PM
#20
Member
Re: Cpu Utilization in vb6
Whoops
Code:
Public Function Append(ByVal Text As String, ByVal TextToAppend As String, Optional Delimeter As String = "|") As String
Text = TrimS(Text, Delimeter)
TextToAppend = TrimS(TextToAppend, Delimeter)
If Len(Text) = 0 Then
Append = TextToAppend
ElseIf Len(TextToAppend) > 0 Then
Append = Text & Delimeter & TextToAppend
Else
Append = Text
End If
End Function
Public Function TrimS(ByVal Text As String, TextToTrim As String) As String
TrimS = Trim(Text)
If StartsWith(TrimS, TextToTrim) Then TrimS = Right(TrimS, Len(TrimS) - Len(TextToTrim))
If EndsWith(TrimS, TextToTrim) Then TrimS = Left(TrimS, Len(TrimS) - Len(TextToTrim))
End Function
Public Function StartsWith(Text As String, ToLookFor As String) As Boolean
StartsWith = InStr(Left(Text, Len(ToLookFor)), ToLookFor) = 1
End Function
Public Function EndsWith(Text As String, ToLookFor As String) As Boolean
EndsWith = Right(Text, Len(ToLookFor)) = ToLookFor
End Function
-
Jul 15th, 2021, 05:52 AM
#21
Re: Cpu Utilization in vb6
WMI cannot be relied upon to be present. I have encountered machines where the whole of the WMI namespaces was missing. An upgrade from Win 7 to Win 10 certainly caused one machine to be in this state. Others have reported WMI corruption or failure to update. The results also seem to be ambiguous and not real-time.
-
Jul 15th, 2021, 05:20 PM
#22
Member
Re: Cpu Utilization in vb6
I don't like WMI either, it takes like a full second to get CPU stats and that's just terrible for real time applications...
There's gotta be proper API for this, Task Manager probably doesn't use WMI.
-
Jul 16th, 2021, 11:39 AM
#23
Re: Cpu Utilization in vb6
Originally Posted by neotechni
There's gotta be proper API for this, Task Manager probably doesn't use WMI.
Indeed, there is.
-
Jul 16th, 2021, 01:09 PM
#24
Member
Re: Cpu Utilization in vb6
Originally Posted by Victor Bravo VI
That seems to be code to get the RAM usage of a specific process, this thread is about total CPU usage though
-
Jul 16th, 2021, 01:59 PM
#25
Re: Cpu Utilization in vb6
Originally Posted by neotechni
That seems to be code to get the RAM usage of a specific process, this thread is about total CPU usage though
The Performance Counters API can give you more than just the memory usage of a process — it can also tell you the CPU usage of any process, the utilization of the CPU (including per core/thread stats), disk & network activity, all sorts of system statistics and many more. In the demo in that post, simply uncomment the #Const BrowseforPerformanceCounter line in order to show the Browse Performance Counters dialog where you can choose from a dizzying array of available counters.
-
Jul 17th, 2021, 02:04 PM
#26
Member
Re: Cpu Utilization in vb6
Interesting,
I managed to get the popup to show with the list, but no matter what I click the function that's supposed to return the number of characters returns 0 so the path is always empty.
This would be exactly what I want, if it worked... (Windows 10)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|