View Single Post
  #4   Report Post  
Posted to microsoft.public.excel.programming
Michel Pierron Michel Pierron is offline
external usenet poster
 
Posts: 214
Default Task managers system CPU PercentProcessorTime

Hi Poniente,

Explanation:
A program or application is a set of processes.
A process is a part of a program or application (the "Process handle" or
"Process ID" is the same).
A handle is not an address in memory. It's called a handle because it's
opaque. It's an indirect index into the process handle table, which in turn
contains the pointer to the kernel data structure; usually, a process
contains a lot of handles, which include the one corresponding to the
application.
See below, the "Test" procedure with the added property "Handle Count" and
the Details procedure.

Sub Test()
Const strComputer$ = "."
Dim objWMIService As Object, colProcess As Object, objItem As Object
Dim Ret$, strNameOfUser, strUserDomain, i%: i = 1
Cells.Clear
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcess = objWMIService.ExecQuery("Select * " _
& "from Win32_PerfFormattedData_PerfProc_Process", , 48)
Cells(1, 1) = "Process Name"
Cells(1, 2) = "CPU Usage"
Cells(1, 3) = "Process ID"
Cells(1, 4) = "User name"
Cells(1, 5) = "Domain"
Cells(1, 6) = "Handle count"
For Each objItem In colProcess
If objItem.Name < "Idle" And objItem.Name < "_Total" Then
i = i + 1
Cells(i, 1) = objItem.Name
Cells(i, 2) = objItem.PercentProcessorTime
Cells(i, 3) = objItem.IDProcess
End If
Next
Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process")
For Each objItem In colProcess
i = RowFind(ActiveSheet, 3, objItem.ProcessID, True)
If i Then
Ret = objItem.GetOwner(strNameOfUser, strUserDomain)
Cells(i, 4) = strNameOfUser
Cells(i, 5) = strUserDomain
Cells(i, 6) = objItem.HandleCount ' Added
End If
Next
Set colProcess = Nothing
Set objWMIService = Nothing
Columns("A:E").Columns.AutoFit
End Sub

Private Function RowFind(Sh As Worksheet, ByVal Col As Byte _
, What As Variant, Whole As Boolean) As Long
Dim Word As Range, Who As Byte
If Whole Then Who = 1 Else Who = 2
Set Word = Sh.Columns(Col).Find(What, LookAt:=Who)
If Not Word Is Nothing Then RowFind = Word.Row
End Function

Statements at the beginning of module:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess _
As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

Sub Details()
Const PROCESS_ALL_ACCESS = &H1F0FFF
On Error GoTo 1
Dim hwnd&, PID&, Handle&, Info$
'hwnd = Application.hwnd
hwnd = FindWindow(vbNullString, Application.Caption)
If hwnd Then
Info = "Application handle: " & hwnd
GetWindowThreadProcessId hwnd, PID
If PID Then
Info = Info & vbLf & "PID: " & PID
Handle = OpenProcess(PROCESS_ALL_ACCESS, False, PID)
Info = Info & vbLf & "Process handle: " & Handle
End If
End If
MsgBox Info, 64
Exit Sub
1: MsgBox "Error: " & Err.Number & vbLf & Err.Description & " !", 64
End Sub

Best regards,
MP




"Poniente" a écrit dans le message de
...
Thanks Michel, that works really well! Exactly what I was looking for!

Do you happen to know how to get the process handle from an active
application?
I tried:
Application.hwnd

but my impression is that this does not match the 'ProcessID' output
of your code...

Any chance you can help me out on this one as well?


Best regards,
Poniente


On 21 jul, 14:41, "Michel Pierron" wrote:
HiPoniente;
Adapt something like: