Jump to content

_ProcessListProperties()


PsaltyDS
 Share

Recommended Posts

Greetings,

is it possible to monitor the "System Idle Process" with this script?

I've tried to use zero as PID or "System Idle Process" as process name but I always get "process not running".

Thank you for your time...

Using "System Idle Process" worked for me, so I can't address that.

$Process = 0 did fail, but was easily fixed. Change the following line:

; If $Process = "" Then
If $Process == "" Then

That change was added to the function in Post #1. Thanks for the heads up on the problem.

Merry Christmas!

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Hi and thanks for the reply...

I've followed your suggestions and edited that line.

Anyway here's this piece of code:

#include "ProcessListProperties.au3"

$processName = 0
Local $PollFrequency = 500
Local $PollCount = 12

For $X = 1 to $PollCount

$avRET = _ProcessListProperties($processName)
ConsoleWrite($avRET[1][6])
Sleep($PollFrequency)

Next

The problem is: this script always reports a "System Idle Process" CPU usage at 100% and that's not true since my computer is not completely idle. I'm checking this againts a CPU stress benchmark (Linx).

On the opposite, the script works with other processes and shows correct CPU usage (ie: explorer.exe).

What am I doing wrong?

Thanks...

Edited by Zazza
Link to comment
Share on other sites

Hi and thanks for the reply...

I've followed your suggestions and edited that line.

Anyway here's this piece of code:

#include "ProcessListProperties.au3"

$processName = 0
Local $PollFrequency = 500
Local $PollCount = 12

For $X = 1 to $PollCount

$avRET = _ProcessListProperties($processName)
ConsoleWrite($avRET[1][6])
Sleep($PollFrequency)

Next

The problem is: this script always reports a "System Idle Process" CPU usage at 100% and that's not true since my computer is not completely idle. I'm checking this againts a CPU stress benchmark (Linx).

On the opposite, the script works with other processes and shows correct CPU usage (ie: explorer.exe).

What am I doing wrong?

Thanks...

I don't think you're doing anything wrong. May be a limitation of the Win32_PerfFormattedData_PerfProc_Process interface used. I ran a CPU-sucking script and it reported 87% idle when the figure on task manager was staying close to 0% idle (steady 97% used by the script). Usually it reports 100% for idle. It may be necessary to make a DLL call for a more accurate figure on the idle process.

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I don't think you're doing anything wrong. May be a limitation of the Win32_PerfFormattedData_PerfProc_Process interface used. I ran a CPU-sucking script and it reported 87% idle when the figure on task manager was staying close to 0% idle (steady 97% used by the script). Usually it reports 100% for idle. It may be necessary to make a DLL call for a more accurate figure on the idle process.

:)

Yesterday I was trying a different approach to the problem:

#include "ProcessListProperties.au3"
Local $sum

Local $PollFrequency = 500
    
Local $PollCount = 50
    
For $X = 1 to $PollCount
    
    $avRET = _ProcessListProperties()
    
        for $n = 2 to $avRET[0][0]
        $sum = $sum + $avRET[$n][6]
        Next
    
    ConsoleWrite("idle CPU% = " & (100-$sum) & @CRLF)
    $sum = 0
    
    Sleep($PollFrequency)
    
Next

It's not perfect but at least it can report idle usage in a rough way...

Maybe I could "filter" the AutoIt process from the $sum since this script uses a little CPU time.

What do you think?

Thanks...

Link to comment
Share on other sites

Yesterday I was trying a different approach to the problem:

It's not perfect but at least it can report idle usage in a rough way...

That's OK for a temporary work-around. When I get some time, I'll dig up the DLL call to get CPU idle percentage (or total CPU usage and do the math) directly.

:)

Edit: The DLL function I was looking for is GetSystemTimes in Kernel32.dll.

Here's a simple GUI to show the results:

#include <GuiConstantsEx.au3>
#include <ProgressConstants.au3>
#include <Date.au3>

Global $iLastTime, $iCurrTime = 0
Global $tIdle = DllStructCreate($tagFILETIME), $ptIdle = DllStructGetPtr($tIdle), $iLastIdle, $iCurrIdle = 0
Global $tKernel = DllStructCreate($tagFILETIME), $ptKernel = DllStructGetPtr($tKernel), $iLastKernel, $iCurrKernel = 0
Global $tUser = DllStructCreate($tagFILETIME), $ptUser = DllStructGetPtr($tUser), $iLastUser, $iCurrUser = 0
Global $iIdleTime, $iKernelTime, $iUserTime, $iTotalTime
Global $hGUI, $iTimer = TimerInit()
Global $ctrlIdleProg, $ctrlKernelProg, $ctrlUserProg
Global $ctrlIdleEdit, $ctrlKernelEdit, $ctrlUserEdit
Global $ctrlIdleEdit, $ctrlKernelEdit, $ctrlUserEdit

$hGUI = GUICreate("System Usage Times", 515, 240)
GUICtrlCreateLabel("Idle Time:", 20, 95, 60, 20)
$ctrlIdleEdit = GUICtrlCreateEdit("0%", 20, 125, 60, 20)
$ctrlIdleProg = GUICtrlCreateProgress(90, 20, 75, 200, $PBS_SMOOTH + $PBS_VERTICAL)
GUICtrlCreateLabel("Kernel Time:", 185, 95, 60, 20)
$ctrlKernelEdit = GUICtrlCreateEdit("0%", 185, 125, 60, 20)
$ctrlKernelProg = GUICtrlCreateProgress(255, 20, 75, 200, $PBS_SMOOTH + $PBS_VERTICAL)
GUICtrlCreateLabel("User Time:", 350, 95, 60, 20)
$ctrlUserEdit = GUICtrlCreateEdit("0%", 350, 125, 60, 20)
$ctrlUserProg = GUICtrlCreateProgress(420, 20, 75, 200, $PBS_SMOOTH + $PBS_VERTICAL)

GUISetState()

Do
    If TimerDiff($iTimer) >= 1000 Then
        ; Reset timer
        $iTimer = TimerInit()

        ; Save previous values
        $iLastTime = $iCurrTime
        $iLastIdle = $iCurrIdle
        $iLastKernel = $iCurrKernel
        $iLastUser = $iCurrUser

        ; Get current values
        _GetSystemTimes()

        ; First time through = Initialize only
        If $iLastIdle > 0 Then
            ; Display results
            $iIdleTime = $iCurrIdle - $iLastIdle
            $iKernelTime = $iCurrKernel - $iLastKernel
            $iUserTime = $iCurrUser - $iLastUser
            $iTotalTime = $iCurrTime - $iLastTime
            $iIdleTime = Round(($iIdleTime / $iTotalTime) * 100)
            GUICtrlSetData($ctrlIdleEdit, $iIdleTime & "%")
            GUICtrlSetData($ctrlIdleProg, $iIdleTime)
            $iKernelTime = Round(($iKernelTime / $iTotalTime) * 100)
            GUICtrlSetData($ctrlKernelEdit, $iKernelTime & "%")
            GUICtrlSetData($ctrlKernelProg, $iKernelTime)
            $iUserTime = Round(($iUserTime / $iTotalTime) * 100)
            GUICtrlSetData($ctrlUserEdit, $iUserTime & "%")
            GUICtrlSetData($ctrlUserProg, $iUserTime)
        EndIf
    EndIf
Until GUIGetMsg() = $GUI_EVENT_CLOSE

; Get current Idle/Kernel/User ticks used, and total ticks elapsed
Func _GetSystemTimes()
    Local $aRET = DllCall("kernel32.dll", "int", "GetSystemTimes", "ptr", $ptIdle, "ptr", $ptKernel, "ptr", $ptUser)
    $iCurrIdle = _GetFileTimeTicks($ptIdle)
    $iCurrKernel = _GetFileTimeTicks($ptKernel)
    $iCurrUser = _GetFileTimeTicks($ptUser)
    Local $tStruct = _Date_Time_GetSystemTimeAsFileTime()
    $iCurrTime = _GetFileTimeTicks(DllStructGetPtr($tStruct))
EndFunc   ;==>_GetSystemTimes

; Generate a float integer number from a FILETIME struct
Func _GetFileTimeTicks($pPointer)
    Local $tStruct = DllStructCreate($tagFILETIME, $pPointer)
    Local $floatRET = DllStructGetData($tStruct, "Lo")
    If $floatRET < 0 Then $floatRET += 2 ^ 32
    $floatRET += DllStructGetData($tStruct, "Hi") * 2 ^ 32
    Return $floatRET
EndFunc   ;==>_GetFileTimeTicks

Func _Quit()
    Exit
EndFunc   ;==>_Quit

When you run that, some things stand out: Idle + Kernel + User times do not equal total time passed. In fact Idle + Kernel = more than total time elapsed. I think this is because the System Idle Process is itself a kernel process.

But the idle percentage shown in the GUI above should closely match what you see in the Task Manager for System Idle Process, because it is calculated as a percentage of the actual elapsed time as returned from GetSystemTimeAsFileTime.

Merry Christmas!

;)

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Thanks again Psalty for your contribution.

By the way, now I'll try to integrate this new function you wrote in my script (as always that this as a noob script, ok? :) ).

#include "ProcessListProperties.au3"
#include <array.au3>

Local $sum
Local $num
Local $total
Local $avg
Local $finished = 0
Local $readings[1]

Local $PollFrequency = 5000
    
TrayTip("Batch Test","Started...",5,1)

While $finished = 0

Sleep($PollFrequency)   

    $avRET = _ProcessListProperties()
    
        for $n = 2 to $avRET[0][0]
        $sum = $sum + $avRET[$n][6]
    Next
    
if $sum<100 then

    _ArrayAdd($readings,$sum)
    $num = $num +1
    
EndIf
    
    if $num = 10 Then
        
        for $a = 1 to Ubound($readings) - 1
            $total = $total + $readings[$a]
        Next
        
        $avg = int($total / $a)
        
        If $avg < 4 Then
            $finished = 1
            TrayTip("Batch Test","Computer in idle status.",10,1)
Sleep(10000)
Exit
Else
    TrayTip("Batch Test","Waiting for idle status... (" & $avg & ")",10,2)
EndIf

        $num=0
        $total=0
        
        local $readings[1]
        
    EndIf
    
    $sum = 0

Wend

Basically this script "monitors" idle CPU usage, takes 10 readings (discarding erroneous ones) and makes an average of the resulting array. If, through time, this average is below a certain value ("4" seems to work) the computer is considered in an idle state. If not, the loop continues.

What do you think about it?

Thanks again...

Oh... and Merry Christmas to you, too! ;)

Link to comment
Share on other sites

  • 2 weeks later...

First off thank you for this great UDF.

Okay I use this tool to grab process specific CPU and MEM for performance testing and after researching Win32_PerfFormattedData_PerfProc_Process for half a day I think that I may be able to ask the appropriate question here.

I would like to get more precise outputs from this fuction currently the cpu% per process is given in percent I am hoping to be able to pull at least 2 decimal places of precision from this call. Currently I only see whole numbers. I cant seem to figure out how to turn on the CookingType ("PERF_100NSEC_TIMER")if that is the correct call I am not a C++ guru but work with it alot in my position.

So is ther any thing I can change in this UDF to get me the precision I am looking for?

Thanks for taking the time to read this far.

Link to comment
Share on other sites

First off thank you for this great UDF.

Okay I use this tool to grab process specific CPU and MEM for performance testing and after researching Win32_PerfFormattedData_PerfProc_Process for half a day I think that I may be able to ask the appropriate question here.

I would like to get more precise outputs from this fuction currently the cpu% per process is given in percent I am hoping to be able to pull at least 2 decimal places of precision from this call. Currently I only see whole numbers. I cant seem to figure out how to turn on the CookingType ("PERF_100NSEC_TIMER")if that is the correct call I am not a C++ guru but work with it alot in my position.

So is ther any thing I can change in this UDF to get me the precision I am looking for?

Thanks for taking the time to read this far.

I'm not sure what you hope to get. The Win32_PerfFormattedData_PerfOS_Processor interface is doing the work for you, and it's accessed by AutoIt via the COM interface (with an SWbemRefresher in this case). That interface already uses the PERF_100NSEC_TIMER cooking type for properties like PercentIdleTime, and the result is defined as a UINT64 type (note the "INT" part). Since it returns and integer percentage, that's what you have to work with if you use that interface. Frankly, given the overhead involved in using the interface has to interfere with the times allocated to what you're monitoring, better than 1% accurate resolution may not be considered possible in those statistics. That would be a way-over-my-head type of question.

If you leave the WMI interface and use DLLs, as in post #66's example, you might be able to make similar use of the GetProcessTimes and/or QueryProcessCycleTime functions to get 100nsec tick counts and do the math yourself.

;)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • 1 month later...
  • 4 months later...

figured out why i was getting dupes on system idel process.. but i seem to get weird readings for memory.. some are accurate some dont seem to be.

for instance:

system idle process memory usage is 1184129024 and in task manager it says 28k

#include <GUIConstantsEx.au3>
#include <GUIListView.au3>
#include <array.au3>

$asset = "192.11.11.1"

GUICreate("Tasks on " & $asset, 275, 500)
GUISetState(@SW_SHOW)
$test = GUICtrlCreateButton("Refresh Tasks", 45, 470, 80, 20)
$test2 = GUICtrlCreateButton("End Task", 150, 470, 80, 20)
Global $in1 = GUICtrlCreateListView("Task|CPU|Memory", 2, 2, 272, 460, BitOr($LVS_SORTASCENDING,$LVS_SINGLESEL))

_GUICtrlListView_SetColumnWidth($in1, 0, 130)
_GUICtrlListView_SetColumnWidth($in1, 1, 40)
_GUICtrlListView_SetColumnWidth($in1, 2, 60)

$procs = _ProcessListProperties()
_ArrayDisplay($procs)

While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            Exit
        Case $msg = $test
            _ProcessListProperties()
        Case $msg = $test2
            exit1()
    EndSelect
WEnd

Func exit1($asset = $asset)
    $arselect = _GUICtrlListView_GetSelectedIndices($in1, "True")
    If $arselect[0] = "" Then
        MsgBox(0, "Error", "No Selection")
    Else
        $process = _GUICtrlListView_GetItemText($in1, $arselect[1])
        RunWait('taskkill /s ' & $asset & ' /IM "' & $process & '"')
        _ProcessListProperties()
    EndIf
EndFunc   ;==>exit1

;===============================================================================
; Function Name:    _ProcessListProperties()
; Description:   Get various properties of a process, or all processes
; Call With:       _ProcessListProperties( [$Process [, $asset]] )
; Parameter(s):  (optional) $Process - PID or name of a process, default is "" (all)
;          (optional) $asset - remote computer to get list from, default is local
; Requirement(s):   AutoIt v3.2.4.9+
; Return Value(s):  On Success - Returns a 2D array of processes, as in ProcessList()
;            with additional columns added:
;            [0][0] - Number of processes listed (can be 0 if no matches found)
;            [1][0] - 1st process name
;            [1][1] - 1st process PID
;            [1][2] - 1st process Parent PID
;            [1][3] - 1st process owner
;            [1][4] - 1st process priority (0 = low, 31 = high)
;            [1][5] - 1st process executable path
;            [1][6] - 1st process CPU usage
;            [1][7] - 1st process memory usage
;            [1][8] - 1st process creation date/time = "MM/DD/YYY hh:mm:ss" (hh = 00 to 23)
;            [1][9] - 1st process command line string
;            ...
;            [n][0] thru [n][9] - last process properties
; On Failure:      Returns array with [0][0] = 0 and sets @Error to non-zero (see code below)
; Author(s):        PsaltyDS at http://www.autoitscript.com/forum
; Date/Version:   12/01/2009  --  v2.0.4
; Notes:            If an integer PID or string process name is provided and no match is found,
;            then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList)
;          This function requires admin permissions to the target computer.
;          All properties come from the Win32_Process class in WMI.
;            To get time-base properties (CPU and Memory usage), a 100ms SWbemRefresher is used.
;===============================================================================
Func _ProcessListProperties($Process = "")

    Local $sUserName, $sMsg, $sUserDomain, $avProcs, $dtmDate
    Local $avProcs[1][2] = [[0, ""]], $n = 1

    ; Convert PID if passed as string
    If StringIsInt($Process) Then $Process = Int($Process)

    _GUICtrlListView_DeleteAllItems($in1)

    ; Connect to WMI and get process objects
    $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy, (Debug)}!\\" & $asset & "\root\cimv2")
    If IsObj($oWMI) Then
        ; Get collection processes from Win32_Process
        If $Process == "" Then
            ; Get all
            $colProcs = $oWMI.ExecQuery("select * from win32_process")
        ElseIf IsInt($Process) Then
            ; Get by PID
            $colProcs = $oWMI.ExecQuery("select * from win32_process where ProcessId = " & $Process)
        Else
            ; Get by Name
            $colProcs = $oWMI.ExecQuery("select * from win32_process where Name = '" & $Process & "'")
        EndIf

        If IsObj($colProcs) Then
            ; Return for no matches
            If $colProcs.count = 0 Then Return $avProcs

            ; Size the array
            ReDim $avProcs[$colProcs.count + 1][10]
            $avProcs[0][0] = UBound($avProcs) - 1

            ; For each process...
            For $oProc In $colProcs
                ; [n][0] = Process name
                $avProcs[$n][0] = $oProc.name
                ; [n][1] = Process PID
                $avProcs[$n][1] = $oProc.ProcessId
                ; [n][2] = Parent PID
                $avProcs[$n][2] = $oProc.ParentProcessId
                ; [n][3] = Owner
                If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName
                ; [n][4] = Priority
                $avProcs[$n][4] = $oProc.Priority
                ; [n][5] = Executable path
                $avProcs[$n][5] = $oProc.ExecutablePath
                ; [n][8] = Creation date/time
                $dtmDate = $oProc.CreationDate
                If $dtmDate <> "" Then
                    ; Back referencing RegExp pattern from weaponx
                    Local $sRegExpPatt = "\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:.*)"
                    $dtmDate = StringRegExpReplace($dtmDate, $sRegExpPatt, "$2/$3/$1 $4:$5:$6")
                EndIf
                $avProcs[$n][8] = $dtmDate
                ; [n][9] = Command line string
                $avProcs[$n][9] = $oProc.CommandLine

                ; increment index
                $n += 1
            Next
        Else
            SetError(2); Error getting process collection from WMI
        EndIf
        ; release the collection object
        $colProcs = 0

        ; Get collection of all processes from Win32_PerfFormattedData_PerfProc_Process
        ; Have to use an SWbemRefresher to pull the collection, or all Perf data will be zeros
        Local $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
        $colProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet
        $oRefresher.Refresh

        ; Time delay before calling refresher
        Local $iTime = TimerInit()
        Do
            Sleep(20)
        Until TimerDiff($iTime) >= 100
        $oRefresher.Refresh

        ; Get PerfProc data
        For $oProc In $colProcs
            ; Find it in the array
            For $n = 1 To $avProcs[0][0]
                If $avProcs[$n][1] = $oProc.IDProcess Then
                    ; [n][6] = CPU usage
                    $avProcs[$n][6] = $oProc.PercentProcessorTime
                    ; [n][7] = memory usage
                    $avProcs[$n][7] = $oProc.WorkingSet
                    ExitLoop
                EndIf
            Next
        Next
    Else
        SetError(1); Error connecting to WMI
    EndIf

for $n=1 to UBound($avProcs)-1
    GUICtrlCreateListViewItem($avProcs[$n][0] & "|" & $avProcs[$n][6] & "|" & $avProcs[$n][7], $in1)
Next

    ; Return array
;~     Return $avProcs
EndFunc  ;==>_ProcessListProperties
Edited by gcue
Link to comment
Share on other sites

Hmm... The DLL changed that supports the .WorkingSet property to WMI with Vista/2008.

I got the same problem running Vista 32bit, but not another box to test at the moment.

What OS are you running it on? Can you try it on XP/2003 vice Vista/2008/Win7 to see if it's different?

:mellow:

Edit: Got to an XP Pro box, an all the memory readings were right except System Idle Proc. Never noticed it before, but it may have always been so. On Vista, I get wild numbers for memory on every process.

:P

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

  • 8 months later...

Hello Psalty et al,

I needed to get a Process Owner inside an infinite loop, so I removed from _ProcessListProperties($processName) all the lines concerning process performances.

Running the script, I noticed a little memory leak.

This is the modified _ProcessListProperties renamed _ProcessProperties (didn't work a lot: just removed some lines):

;===============================================================================
; Function Name:    _ProcessProperties() based on _ProcessListProperties()
; Description:   Get various properties of a process, or all processes
; Call With:       _ProcessListProperties( [$Process [, $sComputer]] )
; Parameter(s):  (optional) $Process - PID or name of a process, default is "" (all)
;          (optional) $sComputer - remote computer to get list from, default is local
; Requirement(s):   AutoIt v3.2.4.9+
; Return Value(s):  On Success - Returns a 2D array of processes, as in ProcessList()
;            with additional columns added:
;            [0][0] - Number of processes listed (can be 0 if no matches found)
;            [1][0] - 1st process name
;            [1][1] - 1st process PID
;            [1][2] - 1st process Parent PID
;            [1][3] - 1st process owner
;            [1][4] - 1st process priority (0 = low, 31 = high)
;            [1][5] - 1st process executable path
;            [1][6] - 1st process CPU usage
;            [1][7] - 1st process memory usage
;            [1][8] - 1st process creation date/time = "MM/DD/YYY hh:mm:ss" (hh = 00 to 23)
;            [1][9] - 1st process command line string
;            ...
;            [n][0] thru [n][9] - last process properties
; On Failure:      Returns array with [0][0] = 0 and sets @Error to non-zero (see code below)
; Author(s):        PsaltyDS at http://www.autoitscript.com/forum
; Date/Version:   12/01/2009  --  v2.0.4
; Notes:            If an integer PID or string process name is provided and no match is found,
;            then [0][0] = 0 and @error = 0 (not treated as an error, same as ProcessList)
;          This function requires admin permissions to the target computer.
;          All properties come from the Win32_Process class in WMI.
;            To get time-base properties (CPU and Memory usage), a 100ms SWbemRefresher is used.
;===============================================================================
Func _ProcessProperties($Process = "", $sComputer = ".")
    Local $sUserName, $sMsg, $sUserDomain, $avProcs, $dtmDate
    Local $avProcs[1][2] = [[0, ""]], $n = 1

    ; Convert PID if passed as string
    If StringIsInt($Process) Then $Process = Int($Process)

    ; Connect to WMI and get process objects
    $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy, (Debug)}!\\" & $sComputer & "\root\cimv2")
    If IsObj($oWMI) Then
        ; Get collection processes from Win32_Process
        If $Process == "" Then
            ; Get all
            $colProcs = $oWMI.ExecQuery("select * from win32_process")
        ElseIf IsInt($Process) Then
            ; Get by PID
            $colProcs = $oWMI.ExecQuery("select * from win32_process where ProcessId = " & $Process)
        Else
            ; Get by Name
            $colProcs = $oWMI.ExecQuery("select * from win32_process where Name = '" & $Process & "'")
        EndIf

        If IsObj($colProcs) Then
            ; Return for no matches
            If $colProcs.count = 0 Then Return $avProcs

            ; Size the array
            ReDim $avProcs[$colProcs.count + 1][10]
            $avProcs[0][0] = UBound($avProcs) - 1

            ; For each process...
            For $oProc In $colProcs
                ; [n][0] = Process name
                $avProcs[$n][0] = $oProc.name
                ; [n][1] = Process PID
                $avProcs[$n][1] = $oProc.ProcessId
                ; [n][2] = Parent PID
                $avProcs[$n][2] = $oProc.ParentProcessId
                ; [n][3] = Owner
                If $oProc.GetOwner($sUserName, $sUserDomain) = 0 Then $avProcs[$n][3] = $sUserDomain & "\" & $sUserName
                ; [n][4] = Priority
                $avProcs[$n][4] = $oProc.Priority
                ; [n][5] = Executable path
                $avProcs[$n][5] = $oProc.ExecutablePath
                ; [n][8] = Creation date/time
                $dtmDate = $oProc.CreationDate
                If $dtmDate <> "" Then
                    ; Back referencing RegExp pattern from weaponx
                    Local $sRegExpPatt = "\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:.*)"
                    $dtmDate = StringRegExpReplace($dtmDate, $sRegExpPatt, "$2/$3/$1 $4:$5:$6")
                EndIf
                $avProcs[$n][8] = $dtmDate
                ; [n][9] = Command line string
                $avProcs[$n][9] = $oProc.CommandLine

                ; increment index
                $n += 1
            Next
        Else
            SetError(2); Error getting process collection from WMI
        EndIf
        
        ; release the collection object
        $colProcs = 0
       
        
       
    Else
        SetError(1); Error connecting to WMI
    EndIf

    ; Return array
    Return $avProcs
EndFunc  ;==>_ProcessListProperties

and here comes a test script:

#Include "..\include\ProcessProperties.au3"
#include <array.au3>
#include <file.au3>

Dim $avRET[10]=[1,2,3,4,5,6,7,8,9,10]
$logDir=@ScriptDir & "\logs"
if NOT FileExists($logDir) Then DirCreate($logDir)
    
while 1
    sleep (2000)
    $logFile=$logDir&"\"&"test_proc_prop.log"
    $avRET = _ProcessProperties("explorer.exe")
    
    _FileWriteLog($logFile,$avRET[1][3])
Wend

If you comment the line

$avRET = _ProcessProperties("explorer.exe")

and run the script, the memory doesn't change.

When that line is active, the memory periodically increases by 4k.

Tested on Windows XP and Vista.

Am I doing something wrong, or there's something I'm missing?

Thanks for your reply

Stefano

Edited by steff
Link to comment
Share on other sites

The only memory leak I knew of was There is also a to create the SwbemRefresher outside the loop.

If you removed the SwbemRefresher code from your function, then I don't know where your memory leak is coming from. Try the same troubleshooting technique Valik applied to the original problem: translate the function to VBScript and see if it does the same thing (indicating a Microsoft Issue).

:)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

The only memory leak I knew of was There is also a to create the SwbemRefresher outside the loop.

If you removed the SwbemRefresher code from your function, then I don't know where your memory leak is coming from. Try the same troubleshooting technique Valik applied to the original problem: translate the function to VBScript and see if it does the same thing (indicating a Microsoft Issue).

:)

Ok, I'll try that.

Thanks

Link to comment
Share on other sites

  • 1 year later...

Can anyone maximaly simplify this scrip? Only I need to get given process CPU usage:

$CPU = _GetCPUUsage("Proces.exe")

Script should not contain anything else, what makes it slower.

I cant do it - I just learning AutoIt, the script is too much "huge" for me, yet... :huh:

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...