Results 1 to 6 of 6

Thread: Monitor CPU Usage

  1. #1

    Thread Starter
    Member
    Join Date
    Apr 2009
    Posts
    44

    Exclamation Monitor CPU Usage

    this is the code I've been using, but it stopped suddenly and now only works randomly

    GetMonitor("cpu") used to return the CPU usage %

    Now I get:
    AddMonitor (B) -1 is invalid: \\LINAINVERSE\Processor(_Total)\% Processor Time (Unknown Error (-1073738824)) STEP: 2
    Failing here: RV = PdhValidatePathW(StrPtr(Name))

    I know that monitor name is correct, I've googled it, I've used it before, it even works sometimes.

    Code:
    Private Declare Sub GlobalMemoryStatusEx Lib "kernel32" (lpBuffer As MEMORYSTATUSEX)
    Private Type INT64
       LoPart As Long
       HiPart As Long
    End Type
    Private Type MEMORYSTATUSEX
       dwLength As Long
       dwMemoryLoad As Long
       ulTotalPhys As INT64
       ulAvailPhys As INT64
       ulTotalPageFile As INT64
       ulAvailPageFile As INT64
       ulTotalVirtual As INT64
       ulAvailVirtual As INT64
       ulAvailExtendedVirtual As INT64
    End Type
    Public Enum RAM_STAT
        RAM_PHYSICAL
        RAM_TOTAL_PHYSICAL
        RAM_AVAIL_PHYSICAL
        RAM_VIRTUAL
        RAM_TOTAL_VIRTUAL
        RAM_AVAIL_VIRTUAL
        RAM_PAGEFILE
        RAM_TOTAL_PAGEFILE
        RAM_AVAIL_PAGEFILE
        RAM_EXTENDED_VIRTUAL
    End Enum
    Private Declare Function GetCurrentProcessId Lib "kernel32.dll" () As Long
    Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal handle As Long) As Long
    Private Declare Function GetModuleBaseName Lib "psapi" Alias "GetModuleBaseNameW" (ByVal hProcess As Long, ByVal hModule As Long, ByVal lpBaseName As Long, ByVal nSize As Long) As Long
    Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As Long) As Long
    Private Const API_NULL As Long = 0
    Private Const PROCESS_QUERY_INFORMATION As Long = 1024 
    Private Const PROCESS_VM_READ As Long = 16
    
    Private m_hQuery As Long
    Private Const PDH_MAX_COUNTER_PATH As Long = 2048
    Public Enum PDH_STATUS
        PDH_ERROR_SUCCESS = 0
        PDH_CSTATUS_VALID_DATA = &H20000000
        PDH_CSTATUS_NEW_DATA = &H20000001
        PDH_CSTATUS_NO_MACHINE = &HA00007D0
        PDH_CSTATUS_NO_INSTANCE = &HA00007D1
        PDH_MORE_DATA = &HA00007D2
        PDH_CSTATUS_ITEM_NOT_VALIDATED = &HA00007D3
        PDH_RETRY = &HA00007D4
        PDH_NO_DATA = &HA00007D5
        PDH_CALC_NEGATIVE_DENOMINATOR = &HA00007D6
        PDH_CALC_NEGATIVE_TIMEBASE = &HA00007D7
        PDH_CALC_NEGATIVE_VALUE = &HA00007D8
        PDH_DIALOG_CANCELLED = &HA00007D9
        PDH_CSTATUS_NO_OBJECT = &HE0000BB8
        PDH_CSTATUS_NO_COUNTER = &HE0000BB9
        PDH_CSTATUS_INVALID_DATA = &HE0000BBA
        PDH_MEMORY_ALLOCATION_FAILURE = &HE0000BBB
        PDH_INVALID_HANDLE = &HE0000BBC
        PDH_INVALID_ARGUMENT = &HE0000BBD
        PDH_FUNCTION_NOT_FOUND = &HE0000BBE
        PDH_CSTATUS_NO_COUNTERNAME = &HE0000BBF
        PDH_CSTATUS_BAD_COUNTERNAME = &HE0000BC0
        PDH_INVALID_BUFFER = &HE0000BC1
        PDH_INSUFFICIENT_BUFFER = &HE0000BC2
        PDH_CANNOT_CONNECT_MACHINE = &HE0000BC3
        PDH_INVALID_PATH = &HE0000BC4
        PDH_INVALID_INSTANCE = &HE0000BC5
        PDH_INVALID_DATA = &HE0000BC6
        PDH_NO_DIALOG_DATA = &HE0000BC7
        PDH_CANNOT_READ_NAME_STRINGS = &HE0000BC8
    End Enum
    Public Enum PERF_DETAIL
        PERF_DETAIL_NOVICE = 100
        PERF_DETAIL_ADVANCED = 200
        PERF_DETAIL_EXPERT = 300
        PERF_DETAIL_WIZARD = 400
    End Enum
    Private Declare Function PdhVbOpenQuery Lib "pdh.dll" (ByRef QueryHandle As Long) As PDH_STATUS
    Private Declare Function PdhVbAddCounter Lib "pdh.dll" (ByVal QueryHandle As Long, ByVal CounterPath As String, ByRef CounterHandle As Long) As PDH_STATUS
    Private Declare Function PdhVbRemoveCounter Lib "pdh.dll" (ByVal CounterHandle As Long) As PDH_STATUS
    Private Declare Function PdhCollectQueryData Lib "pdh.dll" (ByVal QueryHandle As Long) As PDH_STATUS
    Private Declare Function PdhCloseQuery Lib "pdh.dll" (ByVal QueryHandle As Long) As PDH_STATUS
    Private Declare Function PdhVbGetDoubleCounterValue Lib "pdh.dll" (ByVal CounterHandle As Long, ByRef CounterStatus As Long) As Double
    Private Declare Function PdhVbGetOneCounterPath Lib "pdh.dll" (ByVal PathString As String, ByVal PathLength As Long, ByVal DetailLevel As Long, ByVal CaptionString As String) As Long
    Public Declare Function PdhCreateCounterPathList Lib "pdh.dll" Alias "PdhVbCreateCounterPathList" (ByVal DetailLevel As Long, ByVal CaptionString As String) As Long
    Public Declare Function PdhGetCounterPathFromList Lib "pdh.dll" Alias "PdhVbGetCounterPathFromList" (ByVal Index As Long, ByVal Buffer As String, ByVal BufferLength As Long) As Long
    Public Declare Function PdhGetCounterPathElements Lib "pdh.dll" Alias "PdhVbGetCounterPathElements" (ByVal PathString As String, ByVal MachineName As String, ByVal ObjectName As String, ByVal InstanceName As String, ByVal ParentInstance As String, ByVal CounterName As String, ByVal BufferSize As Long) As Long
    Private Declare Function PdhVbIsGoodStatus Lib "pdh.dll" (ByVal StatusValue As Long) As Long
    Private Declare Function PdhAddEnglishCounterW Lib "pdh.dll" (ByVal QueryHandle As Long, ByVal lpCounterPath As Long, ByVal dwUserData As Long, ByRef CounterHandle As Long) As Long
    Private Declare Function PdhValidatePathW Lib "pdh.dll" (ByVal lpCounterPath As Long) As PDH_STATUS 'use strptr(path name)
    Private Declare Function SysReAllocStringLen Lib "oleaut32.dll" (ByVal pBSTR As Long, Optional ByVal pszStrPtr As Long, Optional ByVal Length As Long) As Long
    Public Type PerformanceCounter
        Path As String
        Category As String
        Name As String
        MonitorID As Long
        Value As Double
        LastUpdate As Currency
        NickName As String
    End Type
    Public PerformanceCounters() As PerformanceCounter, CounterCount As Long
    Public Enum CounterPart
        CP_PATH
        CP_CATEGORY
        CP_NAME
        CP_NICKNAME
        CP_MONITOR
    End Enum
    Public Enum PerformanceShortcuts
        PS_CPU
        PS_RAM
        PS_TEMP
        AN_BAT
        [_Last] = 3
    End Enum
    Public Function IsArtificialMonitor(Name As String) As Boolean
        Dim tempstr() As String
        If Len(Name) > 0 Then
            tempstr = Split(VirtualMonitr, "|")
            IsArtificialMonitor = IndexOf(tempstr, Name, -1, vbTextCompare) > -1
        End If
    End Function
    Public Function PDH_GetFromINI(NickName As String, Stat As String, Optional Default As String) As String
        PDH_GetFromINI = Default
        If Len(NickName) > 0 Then
            PDH_GetFromINI = GetINISetting(INIFILE, NickName & " panel", Stat, Default)
        End If
    End Function
    Public Function Difference(Val1 As Double, Val2 As Double) As Double
        Difference = Abs(Val1 - Val2)
    End Function
    Public Function PerformanceShortcut(ID As PerformanceShortcuts, Optional IncludeCPUname As Boolean = True) As String
        Select Case ID
            Case PS_CPU: PerformanceShortcut = "Processor(_Total)\% Processor Time"
            Case PS_RAM: PerformanceShortcut = "Memory\Available MBytes"
            Case PS_TEMP: PerformanceShortcut = "Thermal Zone Information\Temperature" 'Kelvin
            Case AN_BAT: PerformanceShortcut = "android\battery": IncludeCPUname = False
        End Select
        If Len(PerformanceShortcut) > 0 And IncludeCPUname Then
            PerformanceShortcut = "\\" & Environ("computername") & "\" & PerformanceShortcut
        Else
            PerformanceShortcut = "\" & PerformanceShortcut
        End If
    End Function
    Public Function GetNickname(Name As String, Optional MustMatch As Boolean) As String
        Select Case Name
            Case "all": GetNickname = "cpu,ram," & Replace(VirtualMonitr, "|", ",")
            Case PerformanceShortcut(PS_CPU, False), PerformanceShortcut(PS_CPU, True): GetNickname = "cpu"
            Case PerformanceShortcut(PS_RAM, False), PerformanceShortcut(PS_RAM, True): GetNickname = "ram"
            Case PerformanceShortcut(PS_TEMP, False), PerformanceShortcut(PS_TEMP, True): GetNickname = "temp"
            Case Else: GetNickname = IIf(MustMatch, "", Name)
        End Select
    End Function
    Public Function GetPerformanceShortcut(NickName As String) As PerformanceShortcuts
        GetPerformanceShortcut = -1
        Select Case LCase(NickName)
            Case "cpu": GetPerformanceShortcut = PS_CPU
            Case "ram": GetPerformanceShortcut = PS_RAM
            Case "temp": GetPerformanceShortcut = PS_TEMP
        End Select
    End Function
    Public Function CleanPerformanceName(ByVal Name As String) As String
        If IsNumeric(Name) Then
            Name = PerformanceShortcut(CLng(Name))
        ElseIf Not IsArtificialMonitor(Name) And Not TextContains(Name, "\") Then
            Name = PerformanceShortcut(GetPerformanceShortcut(Name))
        End If
        CleanPerformanceName = Name
    End Function
    Public Function StartMonitor(Optional ByVal m_sCounterPath As String, Optional DetailLevel As PERF_DETAIL = PERF_DETAIL_WIZARD, Optional Title As String = "Browse Performance Counters", Optional AllowMultiple As Boolean = False) As Long
        Dim RV As Long, MonitorID As Long, temp As Long, IsArtificial As Boolean
        StartMonitor = -1
        IsArtificial = IsArtificialMonitor(m_sCounterPath)
        If m_hQuery = 0 And Not IsArtificial Then
            RV = PdhVbOpenQuery(m_hQuery)
            Debug.Assert RV = PDH_ERROR_SUCCESS
        End If
        If Len(m_sCounterPath) = 0 Then
            If AllowMultiple Then
                RV = PdhCreateCounterPathList(DetailLevel, Title)
            Else
                m_sCounterPath = String(PDH_MAX_COUNTER_PATH, " ")
                RV = PdhVbGetOneCounterPath(m_sCounterPath, PDH_MAX_COUNTER_PATH, DetailLevel, Title)
            End If
        ElseIf Not IsArtificial Then
            m_sCounterPath = CleanPerformanceName(m_sCounterPath)
            RV = Len(m_sCounterPath)
            If Len(RV) = 0 Then Exit Function
        End If
        If AllowMultiple And Not IsArtificial Then
            For temp = 0 To RV - 1
                m_sCounterPath = String(PDH_MAX_COUNTER_PATH, " ")
                RV = PdhGetCounterPathFromList(temp, VarPtr(m_sCounterPath), PDH_MAX_COUNTER_PATH)
                AddMonitor m_sCounterPath, RV, temp
            Next
        ElseIf IsArtificial Then 'If LenB(m_sCounterPath) > 0 Then
            StartMonitor = SetVirtualMonitor(m_sCounterPath, -1) '
        Else
            StartMonitor = AddMonitor(m_sCounterPath, RV)
        End If
    End Function
    Public Function SetVirtualMonitor(Name As String, Optional Value As Double = MinLong) As Long
        SetVirtualMonitor = AddMonitor(Name, Len(Name), -2, Value)
    End Function
    Private Function AddMonitor(ByVal Name As String, Length As Long, Optional Index As Long = -1, Optional Value As Double = MinLong) As Long
        Dim MonitorID As Long, RV As Long, Step As Long
        MonitorID = -1
        AddMonitor = -1
        If Length = 0 And Index > -2 Then
            Debug.Print "Name " & Index & " was empty"
        ElseIf Len(Name) > 0 Then
            Name = Left$(Name, Length)
            RV = FindMonitor(Name, CP_PATH, False)
            If RV > -1 Then
                With PerformanceCounters(RV)
                    If Value > MinLong Then .Value = Value
                    .LastUpdate = BigTimer
                End With
            Else
                RV = PDH_ERROR_SUCCESS
                If Index > -2 Then
                    Step = 1                
                    RV = PdhValidatePathW(StrPtr(Name))
                End If
                If RV = PDH_ERROR_SUCCESS Then
                    If Index > -2 Then
                        Step = 4
                        RV = PdhVbAddCounter(m_hQuery, Name, MonitorID)
                    End If
                    If RV = PDH_ERROR_SUCCESS Then
                        Step = 5
                        AddMonitor = MonitorID
                        CounterCount = CounterCount + 1
                        ReDim Preserve PerformanceCounters(CounterCount)
                        With PerformanceCounters(CounterCount - 1)
                            If Index = -2 Then
                                Step = 6
                                Name = PerformanceShortcut(GetPerformanceShortcut(Name))
                            End If
                            .Path = Name
                            If Index > -2 Then
                                Name = GetSide(Replace(Name, "\\", ""), "\", False) 
                            End If
                            .Category = GetSide(Name, "\", True)
                            .Name = GetSide(Name, "\", False)
                            .MonitorID = MonitorID
                            .LastUpdate = BigTimer
                            .NickName = GetNickname(Name)
                            .Threshold = PDH_GetFromINI(.NickName, "threshold", "0")
                            .Value = Value
                            If Index > -2 Then
                                Step = 7
                                .Value = QueryMonitorValue(CounterCount - 1)
                            End If
                            .HeldValue = .Value
                        End With
                        Step = 7
                        QueryMonitors CounterCount - 1, , , "AddMonitor"
                    Else
                        Debug.Print "AddMonitor (A) " & Index & " errored: " & Name & " (" & PDHError(RV) & ") STEP: " & Step
                    End If
                Else
                    Debug.Print "AddMonitor (B) " & Index & " is invalid: " & Name & " (" & PDHError(RV) & ") STEP: " & Step
                End If
            End If
        End If
    End Function
    
    Public Function QueryMonitorValue(Index As Long, Optional ByRef Clear As Boolean) As Double
        With PerformanceCounters(Index)
            If .MonitorID > -1 Then 
                Select Case .NickName
                    Case "ram"
                        .Value = PrintRamInformation(RAM_PHYSICAL)
                        .LastUpdate = BigTimer
                    Case Else
                        .Value = QueryMonitor(.MonitorID)
                        .LastUpdate = BigTimer
                        Clear = True
                End Select
            End If
            QueryMonitorValue = .Value
        End With
    End Function
    
    Private Function QueryMonitor(MonitorID As Long) As Double
        Dim RV As Long, CtrStatus As Long, CtrValue As Double
        RV = PdhCollectQueryData(m_hQuery)
        If RV = PDH_ERROR_SUCCESS Then
            CtrValue = PdhVbGetDoubleCounterValue(MonitorID, CtrStatus)
            If PdhVbIsGoodStatus(CtrStatus) Then
                QueryMonitor = CtrValue
            End If
        End If
    End Function
    
    Public Function QueryMonitors(Optional Index As Long = -1, Optional Clear As Boolean, Optional OnlyIfThreshold As Boolean = False, Optional Why As String = "Unknown") As Boolean
        If Index = -1 Then
            For Index = 0 To CounterCount - 1
                If QueryMonitors(Index, , , Why) Then QueryMonitors = True
            Next
            If Clear Then ClearUpdates "QueryMonitors (" & Why & ")"
        Else
            Clear = False
            With PerformanceCounters(Index)
                If (OnlyIfThreshold And .Threshold > 0) Or Not OnlyIfThreshold Then
                    If Not .NeedsUpdate And .Threshold > 0 Then
                        If Difference(.Value, .HeldValue) >= .Threshold Then
                            .NeedsUpdate = True
                            .HeldValue = .Value
                            QueryMonitors = True
                        End If
                    End If
                End If
            End With
        End If
    End Function
    
    Public Sub ClearUpdates(Optional Why As String)
        Dim temp As Long
        Debug.Print "ClearUpdates: " & Why
        For temp = 0 To CounterCount - 1
            With PerformanceCounters(temp)
                .HeldValue = .Value
                .NeedsUpdate = False
            End With
        Next
        PanelPollingTime = GetINISetting(INIFILE, "settings", "panelpollingtime", "0", True)
        SecondsTillUpdate = PanelPollingTime
        If SecondsTillUpdate < 1 Or SecondsTillUpdate > 59 Then SecondsTillUpdate = -1
    End Sub
    Public Function RemoveMonitor(ByVal Name As Variant, Optional Part As CounterPart = CP_PATH) As Boolean
        Dim temp As Long
        temp = FindMonitor(Name, Part, False)
        If temp > -1 Then
            For temp = temp To CounterCount - 2
                PerformanceCounters(temp) = PerformanceCounters(temp + 1)
            Next
            CounterCount = CounterCount - 1
            If CounterCount > 0 Then
                ReDim Preserve PerformanceCounters(CounterCount)
            Else
                ReDim PerformanceCounters(0)
            End If
            RemoveMonitor = True
        End If
    End Function
    Public Function FindMonitor(ByVal Name As Variant, Optional Part As CounterPart = CP_PATH, Optional AddIfNotFound As Boolean = True) As Long
        Dim temp As Long, Value As String, OriginalName As String
        FindMonitor = -1
        If IsNumeric(Name) Then
            Name = PerformanceShortcut(CLng(Name))
            Part = CP_PATH
        End If
        If Part = CP_PATH Then Name = CleanPerformanceName(CStr(Name))
        OriginalName = Name
        Name = LCase(Name)
        For temp = 0 To CounterCount - 1
            With PerformanceCounters(temp)
                If .MonitorID = -1 Then
                    If not TextContains(CStr(Name), "\") Then
                        Value = LCase(.NickName)
                    End If
                Else
                    Select Case Part
                        Case CP_PATH: Value = LCase(.Path)
                        Case CP_CATEGORY: Value = LCase(.Category)
                        Case CP_NAME: Value = LCase(.Name)
                        Case CP_NICKNAME: Value = LCase(.NickName)
                        Case CP_MONITOR: Value = .MonitorID
                    End Select
                End If
                If Name = Value Then
                    FindMonitor = temp
                    Exit Function
                End If
            End With
        Next
        If Part = CP_NICKNAME Or Not TextContains(OriginalName, "\") Then
            Name = CleanPerformanceName(OriginalName)
            Part = CP_PATH
        End If
        If Part = CP_PATH And AddIfNotFound Then
            If StartMonitor(OriginalName) <> 0 Then
                FindMonitor = CounterCount - 1
            End If
        End If
    End Function
    Public Function GetMonitor(ByVal Name As Variant, Optional Query As Boolean, Optional Part As CounterPart = CP_PATH) As Double
        Dim temp As Long
        GetMonitor = -1
        temp = FindMonitor(Name, Part)
        If temp > -1 Then
            If Query Then QueryMonitors temp, , , "GetMonitor"
            GetMonitor = PerformanceCounters(temp).Value
        End If
    End Function
    Public Function StopMonitor() As Boolean
        If m_hQuery <> 0 Then StopMonitor = PdhCloseQuery(m_hQuery) = PDH_ERROR_SUCCESS
    End Function
    Public Function PDHError(ErrorCode As PDH_STATUS) As String
        Select Case ErrorCode
            Case PDH_ERROR_SUCCESS:PDHError = "Success"
            Case PDH_CSTATUS_VALID_DATA:PDHError = "PDH_CSTATUS_VALID_DATA"
            Case PDH_CSTATUS_NEW_DATA:PDHError = "PDH_CSTATUS_NEW_DATA"
            Case PDH_CSTATUS_NO_MACHINE:PDHError = "PDH_CSTATUS_NO_MACHINE"
            Case PDH_CSTATUS_NO_INSTANCE:PDHError = "PDH_CSTATUS_NO_INSTANCE"
            Case PDH_MORE_DATA:PDHError = "PDH_MORE_DATA"
            Case PDH_CSTATUS_ITEM_NOT_VALIDATED:PDHError = "PDH_CSTATUS_ITEM_NOT_VALIDATED"
            Case PDH_RETRY:PDHError = "PDH_RETRY"
            Case PDH_NO_DATA:PDHError = "PDH_NO_DATA"
            Case PDH_CALC_NEGATIVE_DENOMINATOR:PDHError = "PDH_CALC_NEGATIVE_DENOMINATOR"
            Case PDH_CALC_NEGATIVE_TIMEBASE:PDHError = "PDH_CALC_NEGATIVE_TIMEBASE"
            Case PDH_CALC_NEGATIVE_VALUE:PDHError = "PDH_CALC_NEGATIVE_VALUE"
            Case PDH_DIALOG_CANCELLED:PDHError = "PDH_DIALOG_CANCELLED"
            Case PDH_CSTATUS_NO_OBJECT:PDHError = "PDH_CSTATUS_NO_OBJECT"
            Case PDH_CSTATUS_NO_COUNTER:PDHError = "PDH_CSTATUS_NO_COUNTER"
            Case PDH_CSTATUS_INVALID_DATA:PDHError = "PDH_CSTATUS_INVALID_DATA"
            Case PDH_MEMORY_ALLOCATION_FAILURE:PDHError = "PDH_MEMORY_ALLOCATION_FAILURE"
            Case PDH_INVALID_HANDLE:PDHError = "PDH_INVALID_HANDLE"
            Case PDH_INVALID_ARGUMENT:PDHError = "PDH_INVALID_ARGUMENT"
            Case PDH_FUNCTION_NOT_FOUND: PDHError = "PDH_FUNCTION_NOT_FOUND"
            Case PDH_CSTATUS_NO_COUNTERNAME: PDHError = "PDH_CSTATUS_NO_COUNTERNAME"
            Case PDH_CSTATUS_BAD_COUNTERNAME:PDHError = "PDH_CSTATUS_BAD_COUNTERNAME"
            Case PDH_INVALID_BUFFER:PDHError = "PDH_INVALID_BUFFER"
            Case PDH_INSUFFICIENT_BUFFER: PDHError = "PDH_INSUFFICIENT_BUFFER"
            Case PDH_CANNOT_CONNECT_MACHINE: PDHError = "PDH_CANNOT_CONNECT_MACHINE"
            Case PDH_INVALID_PATH: PDHError = "PDH_INVALID_PATH"
            Case PDH_INVALID_INSTANCE: PDHError = "PDH_INVALID_INSTANCE"
            Case PDH_INVALID_DATA: PDHError = "PDH_INVALID_DATA"
            Case PDH_NO_DIALOG_DATA: PDHError = "PDH_NO_DIALOG_DATA"
            Case PDH_CANNOT_READ_NAME_STRINGS: PDHError = "PDH_CANNOT_READ_NAME_STRINGS"
            Case Else: PDHError = "Unknown Error (" & ErrorCode & ")"
        End Select
    End Function
    
    Public Function PrintRamInformation(Optional Stat As RAM_STAT = -1) As Double
        Dim udtMemStatEx As MEMORYSTATUSEX, wVal As INT64, tVal As INT64, Invert As Boolean
        udtMemStatEx.dwLength = Len(udtMemStatEx)
        Call GlobalMemoryStatusEx(udtMemStatEx)
        If Stat > -1 Then
            Select Case Stat 'returns the percentage (available/total*100)
                Case RAM_PHYSICAL
                    tVal = udtMemStatEx.ulTotalPhys
                    wVal = udtMemStatEx.ulAvailPhys
                    Invert = True
                Case RAM_VIRTUAL
                    tVal = udtMemStatEx.ulTotalVirtual
                    wVal = udtMemStatEx.ulAvailVirtual
                    Invert = True
                Case RAM_PAGEFILE
                    tVal = udtMemStatEx.ulTotalPageFile
                    wVal = udtMemStatEx.ulAvailPageFile
                    Invert = True
                Case Else 'returns the number of bytes, use NumberInKB on these values
                    Select Case Stat
                        Case RAM_TOTAL_PHYSICAL: wVal = udtMemStatEx.ulTotalPhys
                        Case RAM_AVAIL_PHYSICAL: wVal = udtMemStatEx.ulAvailPhys
                        Case RAM_TOTAL_VIRTUAL: wVal = udtMemStatEx.ulTotalVirtual
                        Case RAM_AVAIL_VIRTUAL: wVal = udtMemStatEx.ulAvailVirtual
                        Case RAM_TOTAL_PAGEFILE: wVal = udtMemStatEx.ulTotalPageFile
                        Case RAM_AVAIL_PAGEFILE: wVal = udtMemStatEx.ulAvailPageFile
                        Case RAM_EXTENDED_VIRTUAL: wVal = udtMemStatEx.ulAvailExtendedVirtual
                    End Select
                    PrintRamInformation = CLargeInt(wVal.LoPart, wVal.HiPart)
                    Exit Function
            End Select
            PrintRamInformation = (CLargeInt(wVal.LoPart, wVal.HiPart) / CLargeInt(tVal.LoPart, tVal.HiPart)) * 100
            If Invert Then PrintRamInformation = 100 - PrintRamInformation
        End If
    End Function
    Private Function CLargeInt(Lo As Long, Hi As Long) As Double
       Dim dblLo As Double, dblHi As Double
       If Lo < 0 Then
          dblLo = 2 ^ 32 + Lo
       Else
          dblLo = Lo
       End If
       If Hi < 0 Then
          dblHi = 2 ^ 32 + Hi
       Else
          dblHi = Hi
       End If
       CLargeInt = dblLo + dblHi * 2 ^ 32
    End Function

  2. #2

    Thread Starter
    Member
    Join Date
    Apr 2009
    Posts
    44

    Re: how do i find cpu usage?

    So it turns out all those error code values were wrong (even though they were copy/pasted from somewhere...), and upon correcting them, the error in question is:

    PDH_CSTATUS_NO_OBJECT 'The specified object is not found on the system

    Code:
    Public Enum PDH_STATUS '7FFFF448 2147480648
        PDH_ERROR_SUCCESS = 0                       'The returned data is valid
        PDH_CSTATUS_VALID_DATA = &H20000000
        PDH_CSTATUS_NEW_DATA = &H1                  'The return data value is valid and different from the last sample.
        PDH_CSTATUS_NO_MACHINE = &H800007D0         'Unable to connect to the specified computer, or the computer is offline.
        PDH_CSTATUS_NO_INSTANCE = &H800007D1        'The specified instance is not present.
        PDH_MORE_DATA = &H800007D2                  'There is more data to return than would fit in the supplied buffer. Allocate a larger buffer and call the function again
        PDH_CSTATUS_ITEM_NOT_VALIDATED = &H800007D3 'The data item has been added to the query but has not been validated nor accessed. No other status information on this data item is available
        PDH_RETRY = &H800007D4                      'The selected operation should be retried
        PDH_NO_DATA = &H800007D5                    'No data to return
        PDH_CALC_NEGATIVE_DENOMINATOR = &H800007D6  'A counter with a negative denominator value was detected
        PDH_CALC_NEGATIVE_TIMEBASE = &H800007D7     'A counter with a negative time base value was detected
        PDH_CALC_NEGATIVE_VALUE = &H800007D8        'A counter with a negative value was detected
        PDH_DIALOG_CANCELLED = &H800007D9           'The user canceled the dialog box
        
        PDH_END_OF_LOG_FILE = &H800007DA            'The end of the log file was reached.
        PDH_ASYNC_QUERY_TIMEOUT = &H800007DB        'A time-out occurred while waiting for the asynchronous counter collection thread to end.
        PDH_CANNOT_SET_DEFAULT_REALTIME_DATASOURCE = &H800007DC 'Cannot change set default real-time data source. There are real-time query sessions collecting counter data
        
        PDH_CSTATUS_NO_OBJECT = &HC0000BB8          'The specified object is not found on the system
        PDH_CSTATUS_NO_COUNTER = &HC0000BB9         'The specified counter could not be found
        PDH_CSTATUS_INVALID_DATA = &HC0000BBA       'The returned data is not valid
        PDH_MEMORY_ALLOCATION_FAILURE = &HC0000BBB  'A PDH function could not allocate enough temporary memory to complete the operation. Close some applications or extend the page file and retry the function
        PDH_INVALID_HANDLE = &HC0000BBC             'The handle is not a valid PDH object
        PDH_INVALID_ARGUMENT = &HC0000BBD           'A required argument is missing or incorrect
        PDH_FUNCTION_NOT_FOUND = &HC0000BBE         'Unable to find the specified function
        PDH_CSTATUS_NO_COUNTERNAME = &HE0000BBF     'No counter was specified
        PDH_CSTATUS_BAD_COUNTERNAME = &HC0000BC0    'Unable to parse the counter path. Check the format and syntax of the specified path.
        PDH_INVALID_BUFFER = &HC0000BC1             'The buffer passed by the caller is not valid
        PDH_INSUFFICIENT_BUFFER = &HC0000BC2        'The requested data is larger than the buffer supplied. Unable to return the requested data
        PDH_CANNOT_CONNECT_MACHINE = &HC0000BC3     'Unable to connect to the requested computer
        PDH_INVALID_PATH = &HC0000BC4               'The specified counter path could not be interpreted
        PDH_INVALID_INSTANCE = &HC0000BC5           'The instance name could not be read from the specified counter path
        PDH_INVALID_DATA = &HC0000BC6               'The data is not valid
        PDH_NO_DIALOG_DATA = &HC0000BC7             'The dialog box data block was missing or not valid
        PDH_CANNOT_READ_NAME_STRINGS = &HC0000BC8   'Unable to read the counter and/or help text from the specified computer
        
        PDH_LOG_FILE_CREATE_ERROR = &HC0000BC9      'Unable to create the specified log file.
        PDH_LOG_FILE_OPEN_ERROR = &HC0000BCA        'Unable to open the specified log file.
        PDH_LOG_TYPE_NOT_FOUND = &HC0000BCB         'The specified log file type has not been installed on this system.
        PDH_NO_MORE_DATA = &HC0000BCC               'No more data is available.
        PDH_ENTRY_NOT_IN_LOG_FILE = &HC0000BCD      'The specified record was not found in the log file.
        PDH_DATA_SOURCE_IS_LOG_FILE = &HC0000BCE    'The specified data source is a log file.
        PDH_DATA_SOURCE_IS_REAL_TIME = &HC0000BCF   'The specified data source is the current activity.
        PDH_UNABLE_READ_LOG_HEADER = &HC0000BD0     'The log file header could not be read.
        PDH_FILE_NOT_FOUND = &HC0000BD1             'Unable to find the specified file.
        PDH_FILE_ALREADY_EXISTS = &HC0000BD2        'There is already a file with the specified file name.
        PDH_NOT_IMPLEMENTED = &HC0000BD3            'The function referenced has not been implemented.
        PDH_STRING_NOT_FOUND = &HC0000BD4           'Unable to find the specified string in the list of performance name and help text strings.
        PDH_UNABLE_MAP_NAME_FILES = &H80000BD5      'Unable to map to the performance counter name data files. The data will be read from the registry and stored locally.
        PDH_UNKNOWN_LOG_FORMAT = &HC0000BD6         'The format of the specified log file is not recognized by the PDH DLL.
        PDH_UNKNOWN_LOGSVC_COMMAND = &HC0000BD7     'The specified Log Service command value is not recognized.
        PDH_LOGSVC_QUERY_NOT_FOUND = &HC0000BD8     'The specified query from the Log Service could not be found or could not be opened.
        PDH_LOGSVC_NOT_OPENED = &HC0000BD9          'The Performance Data Log Service key could not be opened. This may be due to insufficient privilege or because the service has not been installed.
        PDH_WBEM_ERROR = &HC0000BDA                 'An error occurred while accessing the WBEM data store.
        PDH_ACCESS_DENIED = &HC0000BDB              'Unable to access the desired computer or service. Check the permissions and authentication of the log service or the interactive user session against those on the computer or service being monitored.
        PDH_LOG_FILE_TOO_SMALL = &HC0000BDC         'The maximum log file size specified is too small to log the selected counters. No data will be recorded in this log file. Specify a smaller set of counters to log or a larger file size and retry this call.
        PDH_INVALID_DATASOURCE = &HC0000BDD         'Cannot connect to ODBC DataSource Name.
        PDH_INVALID_SQLDB = &HC0000BDE              'SQL Database does not contain a valid set of tables for Perfmon.
        PDH_NO_COUNTERS = &HC0000BDF                'No counters were found for this Perfmon SQL Log Set.
        PDH_SQL_ALLOC_FAILED = &HC0000BE0           'Call to SQLAllocStmt failed with %1.
        PDH_SQL_ALLOCCON_FAILED = &HC0000BE1        'Call to SQLAllocConnect failed with %1.
        PDH_SQL_EXEC_DIRECT_FAILED = &HC0000BE2     'Call to SQLExecDirect failed with %1.
        PDH_SQL_FETCH_FAILED = &HC0000BE3           'Call to SQLFetch failed with %1.
        PDH_SQL_ROWCOUNT_FAILED = &HC0000BE4        'Call to SQLRowCount failed with %1.
        PDH_SQL_MORE_RESULTS_FAILED = &HC0000BE5    'Call to SQLMoreResults failed with %1.
        PDH_SQL_CONNECT_FAILED = &HC0000BE6         'Call to SQLConnect failed with %1.
        PDH_SQL_BIND_FAILED = &HC0000BE7            'Call to SQLBindCol failed with %1.
        PDH_CANNOT_CONNECT_WMI_SERVER = &HC0000BE8  'Unable to connect to the WMI server on requested computer.
        PDH_PLA_COLLECTION_ALREADY_RUNNING = &HC0000BE9 'Collection "%1!s!" is already running.
        PDH_PLA_ERROR_SCHEDULE_OVERLAP = &HC0000BEA 'The specified start time is after the end time.
        PDH_PLA_COLLECTION_NOT_FOUND = &HC0000BEB   'Collection "%1!s!" does not exist.
        PDH_PLA_ERROR_SCHEDULE_ELAPSED = &HC0000BEC 'The specified end time has already elapsed.
        PDH_PLA_ERROR_NOSTART = &HC0000BED          'Collection "%1!s!" did not start; check the application event log for any errors.
        PDH_PLA_ERROR_ALREADY_EXISTS = &HC0000BEE   'Collection "%1!s!" already exists.
        PDH_PLA_ERROR_TYPE_MISMATCH = &HC0000BEF    'There is a mismatch in the settings type.
        PDH_PLA_ERROR_FILEPATH = &HC0000BF0         'The information specified does not resolve to a valid path name.
        PDH_PLA_SERVICE_ERROR = &HC0000BF1          'The "Performance Logs & Alerts" service did not respond.
        PDH_PLA_VALIDATION_ERROR = &HC0000BF2       'The information passed is not valid.
        PDH_PLA_VALIDATION_WARNING = &H80000BF3     'The information passed is not valid.
        PDH_PLA_ERROR_NAME_TOO_LONG = &HC0000BF4    'The name supplied is too long.
        PDH_INVALID_SQL_LOG_FORMAT = &HC0000BF5     'SQL log format is incorrect. Correct format is SQL:<DSN-name>!<LogSet-Name>.
        PDH_COUNTER_ALREADY_IN_QUERY = &HC0000BF6   'Performance counter in PdhAddCounter call has already been added in the performance query. This counter is ignored.
        PDH_BINARY_LOG_CORRUPT = &HC0000BF7         'Unable to read counter information and data from input binary log files.
        PDH_LOG_SAMPLE_TOO_SMALL = &HC0000BF8       'At least one of the input binary log files contain fewer than two data samples.
        PDH_OS_LATER_VERSION = &HC0000BF9           'The version of the operating system on the computer named %1 is later than that on the local computer. This operation is not available from the local computer.
        PDH_OS_EARLIER_VERSION = &HC0000BFA         '%1 supports %2 or later. Check the operating system version on the computer named %3.
        PDH_INCORRECT_APPEND_TIME = &HC0000BFB      'The output file must contain earlier data than the file to be appended.
        PDH_UNMATCHED_APPEND_COUNTER = &HC0000BFC   'Both files must have identical counters in order to append.
        PDH_SQL_ALTER_DETAIL_FAILED = &HC0000BFD    'Cannot alter CounterDetail table layout in SQL database.
        PDH_QUERY_PERF_DATA_TIMEOUT = &HC0000BFE    'System is busy. A time-out occurred when collecting counter data. Please retry later or increase the CollectTime registry value.
    End Enum

  3. #3
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    803

    Re: how do i find cpu usage?

    [Moderator - As this is a c/c++ forum, would this be moved to the appropriate VB forum]
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.4.2)

  4. #4
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,154

    Re: Monitor CPU Usage

    Moderator Action: Moved from C++ to Visual Basic .NET
    "Code is like humor. When you have to explain it, itís bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    37,718

    Re: Monitor CPU Usage

    Further Moderator Action: Moved to Classic VB

    After noticing the way Long is used, I think this is probably VB6.
    My usual boring signature: Nothing

  6. #6
    Powered By Medtronic dbasnett's Avatar
    Join Date
    Dec 2007
    Location
    Pointless Forest 38.517,-92.023
    Posts
    9,510

    Re: Monitor CPU Usage

    In .Net, not sure which versions, there are performance counters available. Finding out the names, etc can be daunting. I use the Performance Monitor application to find what I'm interested in. Here is an example,

    Code:
            Debug.WriteLine("")
            Dim pc As New PerformanceCounter("Processor", "% Processor Time", "_Total", True)
            Debug.WriteLine(pc.NextValue) 'typically the first is zero
            For x As Integer = 1 To 5
                Debug.WriteLine(pc.NextValue)
                Threading.Thread.Sleep(100)
            Next
    My First Computer -- Documentation Link (RT?M) -- Using the Debugger -- Prime Number Sieve
    Counting Bits -- Subnet Calculator -- UI Guidelines -- >> SerialPort Answer <<

    "Those who use Application.DoEvents have no idea what it does and those who know what it does never use it." John Wein

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width