Jump to content
Sign in to follow this  
PsaltyDS

_ProcessListProperties()

Recommended Posts

I've been trying this method out with little success due to the aforementioned memory leak.

It's strange, because I know I've used ADO Objects in loops before, but perhaps it's related more to the object being loaded?

I am also able to "Fix" the problem by commenting the refresh segment out, but unfortunately, I need the process memory. :P

-Mr. Crimson

Share this post


Link to post
Share on other sites

I tried adding this after the For/Next loop for "; Get PerfProc data" in the original:

; Get PerfProc data
        For $oProc In $colProcs
        ; ...
        Next

    ; Release Refresher object
        $oRefresher.DeleteAll
        $oRefresher = 0
        $colProcs = 0

Still had the memory leak. ;)

I moved the creation of $oWMI to a Global variable where it is only created once - and there was still a memory leak. :lmao:

Then I moved the creation of $oRefresher outside the loop to a Global - the leak went away. :D

This does not show the memory leak:

#include <Array.au3>; Only for _ArrayDisplay()

; 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
Global $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\" & @ComputerName & "\root\cimv2")
Global $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
Global $colRefProcs = $oRefresher.AddEnum($oWMI, "Win32_PerfFormattedData_PerfProc_Process" ).objectSet
$oRefresher.Refresh

HotKeySet("{ESC}", "_Quit")

; Loop to watch for memory leak
While 1
    _ProcessListProperties()
    Sleep(20)
WEnd

Func _Quit()
    Exit
EndFunc  ;==>_Quit

;===============================================================================
; Function Name:    _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:   07/02/2008  --  v2.0.2
; 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 = "", $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}!\\" & $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

        $oRefresher.Refresh

    ; Get PerfProc data
        For $oProc In $colRefProcs
        ; 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

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

So, if you have to repeat the function in a tight loop, this code might help - but it doesn't explain why the $oRefresher Swbemrefresher object leaks so bad in a loop.

;)


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

Share this post


Link to post
Share on other sites

Added Debug (SeDebugPrivilege) to the WMI call so fewer fields would be left out (i.e. ExecutablePath for some processes).

:)


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

Share this post


Link to post
Share on other sites

Added Debug (SeDebugPrivilege) to the WMI call so fewer fields would be left out (i.e. ExecutablePath for some processes).

>_<

Wonder where you got that idea :)

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

BugTrac #520 submitted on the SwbemRefresher memory leak issue.

:)

The BugTrac was closed, but the problem is not fixed. Valik poked and prodded it, and demonstrated that the same function coded in VBScript has the same memory leak. So the problem is Microsoft's, not AutoIt's. Don't use the unmodified version of _ProcessListProperties() in a loop until we get a Microsoft fix for the SwbemRefresher.

>_<


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

Share this post


Link to post
Share on other sites

Ya know, there's a mention about a memory leak in SwbemRefresher on VirtualBox's website in regards to their program running under Vista. They provided a link to a Vista hotfix. No mention of XP though...

Share this post


Link to post
Share on other sites

Why am I getting this error message? What I'm doing wrong?

Unable to parse line.:

$colProcs = $oWMI.ExecQuery("select * from win32_process")

$colProcs = $oWMI.E^ ERROR

->14:00:45 AutoIT3.exe ended.rc:1

+>14:00:46 AutoIt3Wrapper Finished

>Exit code: 1 Time: 2.408

Share this post


Link to post
Share on other sites

Why am I getting this error message? What I'm doing wrong?

Unable to parse line.:

$colProcs = $oWMI.ExecQuery("select * from win32_process")

$colProcs = $oWMI.E^ ERROR

->14:00:45 AutoIT3.exe ended.rc:1

+>14:00:46 AutoIt3Wrapper Finished

>Exit code: 1 Time: 2.408

There's a formatting/syntax error in your script. Look for stray (unpaired) quote marks or a missing append (&).

:)


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

Share this post


Link to post
Share on other sites

Sorry, I should have been more clear. Script is the one from the begginig of this post that I just tried to use entirely without any modification or additions. If that one has a formating/syntax error I'm sure that somebody would point to it by now. I still can't compile the script.

There's a formatting/syntax error in your script. Look for stray (unpaired) quote marks or a missing append (&).

:)

Share this post


Link to post
Share on other sites

Sorry, I should have been more clear. Script is the one from the begginig of this post that I just tried to use entirely without any modification or additions. If that one has a formating/syntax error I'm sure that somebody would point to it by now. I still can't compile the script.

He means your script, not the ProcessListProperties() function

This error probably doesn't have anything to do with ProcessListProperties(), that is just where the debugger finds the problem because of something earlier in your script, but you really should post your code if you want a better answer.


[u]You can download my projects at:[/u] Pulsar Software

Share this post


Link to post
Share on other sites

As I mentioned earlier. Script is the one that is on the first post in this thread.

I can copy and paste it in here if you want me.

He means your script, not the ProcessListProperties() function

This error probably doesn't have anything to do with ProcessListProperties(), that is just where the debugger finds the problem because of something earlier in your script, but you really should post your code if you want a better answer.

Share this post


Link to post
Share on other sites

GOT IT! Thanks. After updating my verrsion of Autoit is worked

As I mentioned earlier. Script is the one that is on the first post in this thread.

I can copy and paste it in here if you want me.

Share this post


Link to post
Share on other sites

It was 3.1.1.0 version

That version is older than PsaltyDS

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

===> Important bug note: The SwbemRefresher object has a Microsoft bug that causes a memory leak when called repeatedly. Until a fix is found from Microsoft,

don't use _ProcessListProperties() in a tight loop. <===

Hey,

how tight is tight? Any hint?

thanky, yetrael

Share this post


Link to post
Share on other sites

Hey,

how tight is tight? Any hint?

thanky, yetrael

See for yourself. It doesn't crash your machine or anything that dramatic, so it's safe to test. Just run it in a loop while watching the memory usage of the process in Task Manager.

:D


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

Share this post


Link to post
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...