Sign in to follow this  
Followers 0
nikink

Determine ownership of process

15 posts in this topic

Hi folks, trying to cobble together a simple and generic progress indicator to give some user feedback while a bit of software silently installs.

I have the progress window watch the prosesses and while msiexec.exe exists it just loops continuously to give some visual feedback.

Trouble is, *another* msiexec.exe on the computer is running occasionally, and the progress window watches it instead...

So is there a way to work out what msiexec.exe should be watched? Or what software 'owns' that particular instance? Or the like?

Share this post


Link to post
Share on other sites



Hi folks, trying to cobble together a simple and generic progress indicator to give some user feedback while a bit of software silently installs.

I have the progress window watch the prosesses and while msiexec.exe exists it just loops continuously to give some visual feedback.

Trouble is, *another* msiexec.exe on the computer is running occasionally, and the progress window watches it instead...

So is there a way to work out what msiexec.exe should be watched? Or what software 'owns' that particular instance? Or the like?

I found this reference in MSDN: The Win32_Process WMI class, and based on info from that page, generated this:

#include <array.au3> ; for _ArrayDisplay()

Dim $sComputer = ".", $sUserName, $sMsg, $sUserDomain
Dim $avProcs = ProcessList()
ReDim $avProcs[$avProcs[0][0] + 1][3]

$oWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2")
$colProcesses = $oWMIService.ExecQuery ("select * from win32_process")
For $oProcess In $colProcesses
    If $oProcess.GetOwner ($sUserName, $sUserDomain) = 0 Then
        For $n = 1 To $avProcs[0][0]
            If $avProcs[$n][1] = $oProcess.ProcessId Then
                $avProcs[$n][2] = $sUserDomain & "\" & $sUserName
                ExitLoop
            EndIf
        Next
    EndIf
Next

_ArrayDisplay($avProcs, "Debug: $avProcs")

The above code could be tweaked into several UDF functions, which look handy to me, so I'll work on that later, but this gives you the quick and dirty that I have time for at the moment.

Hope that helps.

:)


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

Turned the WMI call for Win32_Process properties into a function called _ProcessListProperties():

#include <array.au3> ; for _ArrayDisplay()

$avRET = _ProcessListProperties()
_ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error)

$avRET = _ProcessListProperties("WinLogon.exe")
_ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error)

$avRET = _ProcessListProperties("SvcHost.exe")
_ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error)

;===============================================================================
;
; 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, if empty or not
;                       given lists all processes.
;                   (optional) $sComputer - remote computer to get list from
; 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
;                       ...
;                       [n][0] thru [n][5] - 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
; Notes:            If a numeric 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.
;===============================================================================
Func _ProcessListProperties($Process = "", $sComputer = ".")
    Local $sUserName, $sMsg, $sUserDomain, $avProcs
    If $Process = "" Then
        $avProcs = ProcessList()
    Else
        $avProcs = ProcessList($Process)
    EndIf
    
    ; Return for no matches
    If $avProcs[0][0] = 0 Then Return $avProcs
    
    ; ReDim array for additional property columns
    ReDim $avProcs[$avProcs[0][0] + 1][6]
    
    ; Connect to WMI and get process objects
    $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2")
    If IsObj($oWMI) Then
        ; Get collection of all processes
        $colProcs = $oWMI.ExecQuery ("select * from win32_process")
        If IsObj($colProcs) Then
            ; For each process...
            For $oProc In $colProcs
                ; Find it in the array
                For $n = 1 To $avProcs[0][0]
                    If $avProcs[$n][1] = $oProc.ProcessId Then
                        
                        ; [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
                        
                        ExitLoop
                    EndIf
                Next
            Next
        Else
            SetError(2) ; Error getting process collection from WMI
        EndIf
    Else
        SetError(1) ; Error connecting to WMI
    EndIf
    
    ; Return array
    Return $avProcs
EndFunc   ;==>_ProcessListProperties

I would like to add two columns for CPU usage (0-100%) and Mem usage, like in Task view, but they must come from a different WMI call, and I haven't found them yet. Anybody know where I should look for those?

:)


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

#6 ·  Posted (edited)

Both Microsoft products, looks like they serve the same purpose but I don't see many differences. Maybe WMI Code Creator is a little more refined?

Edited by weaponx

Share this post


Link to post
Share on other sites

Both Microsoft products, looks like they serve the same purpose but I don't see many differences. Maybe WMI Code Creator is a little more refined?

Yes Scriptomatic is also microsoft product. I'm just saying there's also Scriptomatic written in AutoIt which serves the purpose by giving you WMI call directly in AutoIt so you don't have to convert it from VBS or anything else. However i'm preety sure Psalty knows about it already and he is just having dificulties of finding right call.

Psalty: you're looking for Processor / Mem usage of each process and not overall right ? Overall seems too simple to find, and you haven't specified it in your request :)


My little company: Evotec (PL version: Evotec)

Share this post


Link to post
Share on other sites

PSalty knows everything, no question about that. If he is having difficulties it's only because WMI does not support his superior brilliance. :)

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

There's Scriptomatic on this forum in AutoIt which generates WMI codes for you. No need to go to microsoft i guess?

The WMI Creator is very cool! Thanks for the tip. :)

However, the code it gave me doesn't work:

strComputer = "." 
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") 
Set colItems = objWMIService.ExecQuery( _
    "SELECT * FROM Win32_PerfFormattedData_PerfProc_Process",,48) 
For Each objItem in colItems 
    Wscript.Echo "-----------------------------------"
    Wscript.Echo "Win32_PerfFormattedData_PerfProc_Process instance"
    Wscript.Echo "-----------------------------------"
    Wscript.Echo "PercentProcessorTime: " & objItem.PercentProcessorTime
Next

It runs without error, but returns 0 for every process.

So I found a tweak for that, and now it works:

#include <array.au3> ; for _ArrayDisplay()

$avRET = _ProcessListProperties()
_ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error)

$avRET = _ProcessListProperties("WinLogon.exe")
_ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error)

$avRET = _ProcessListProperties("SvcHost.exe")
_ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error)

;===============================================================================
;
; 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, if empty or not
;                       given lists all processes.
;                   (optional) $sComputer - remote computer to get list from
; 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
;                       ...
;                       [n][0] thru [n][6] - 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
; Notes:            If a numeric 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.
;===============================================================================
Func _ProcessListProperties($Process = "", $sComputer = ".")
    Local $sUserName, $sMsg, $sUserDomain, $avProcs
    If $Process = "" Then
        $avProcs = ProcessList()
    Else
        $avProcs = ProcessList($Process)
    EndIf
    
    ; Return for no matches
    If $avProcs[0][0] = 0 Then Return $avProcs
    
    ; ReDim array for additional property columns
    ReDim $avProcs[$avProcs[0][0] + 1][7]
    
    ; Connect to WMI and get process objects
    $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2")
    If IsObj($oWMI) Then
        ; Get collection of all processes from Win32_Process
        $colProcs = $oWMI.ExecQuery ("select * from win32_process")
        If IsObj($colProcs) Then
            ; For each process...
            For $oProc In $colProcs
                ; Find it in the array
                For $n = 1 To $avProcs[0][0]
                    If $avProcs[$n][1] = $oProc.ProcessId Then
                        
                        ; [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
                        
                        ExitLoop
                    EndIf
                Next
            Next
        Else
            SetError(2) ; Error getting process collection from WMI
        EndIf
        
        ; 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
        $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
        $colProcs = $oRefresher.AddEnum ($oWMI, "Win32_PerfFormattedData_PerfProc_Process").objectSet
        $oRefresher.Refresh
        Sleep(1000)
        $oRefresher.Refresh
        For $oProc In $colProcs
            ; Find it in the array
            For $n = 1 To $avProcs[0][0]
                If $avProcs[$n][1] = $oProc.IDProcess Then
                    $avProcs[$n][6] = $oProc.PercentProcessorTime
                    ExitLoop
                EndIf
            Next
        Next
    Else
        SetError(1) ; Error connecting to WMI
    EndIf
    
    ; Return array
    Return $avProcs
EndFunc   ;==>_ProcessListProperties

Next step is the memory usage... any more hints?

;)

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

Share this post


Link to post
Share on other sites

Ok, thanks for that help! B-) Now I have some code. Can anyone help me out making what I have faster / more efficient? Especially the bit dealing with the Array comparisons - the 'tricky' code area. I am just confused with these arrays!!! B-(

#NoTrayIcon

#include <array.au3> 

; Simple Progress indicator to provide feedback for PC users 
; who have been blocked from their computers during an SMS deployed software package
; that is totally invisible (ie: does not have any user feedback of it's own)
; to prevent the user from thinking their PC has hung/frozen/crashed etc.
; and thus from forcefully rebooting the computer in the middle of an otherwise ok software install.

Global $WatchProcess = "Notepad.exe"
Global $Title = "Department Name"
Global $msg = ""

Func _GetParams()
    Local $ProcessExtension = " " ; Temp variables to aid in determining if $WatchProcess is an exe or msi or not.
    Local $ValidProcess = False
    
    If Not $CmdLine[0] Then
        MsgBox(0, "Error - no commandline switches found!", "This program must run with cmdline switches. Eg:" & _
        @CRLF & @CRLF & 'GenericProgressIndicator.exe "process" "title" "message" ' & _
        @CRLF & @CRLF & 'Where: ' & _ 
        @CRLF & @CRLF & '"process" is the name of the process being watched. ' & _
        @CRLF & '"title" is the title of the window (set to Department Name by default). ' & _
        @CRLF & '"message" is anything you want the window to display (eg: the name of the software package) (set to blank by default).' & _
        @CRLF & @CRLF & 'While this process is running, this progress indicator will display ' & _
        @CRLF & 'a looping progress bar window with title and message showing.')
        Exit
    Else
        Select
            Case (UBound($CmdLine)-1) = 3
                $WatchProcess = $CmdLine[1]
                $Title = $CmdLine[2]
                $msg = $CmdLine[3]
            Case (UBound($CmdLine)-1) = 2
                $WatchProcess = $CmdLine[1]
                $Title = $CmdLine[2]
            Case (UBound($CmdLine)-1) = 1
                $WatchProcess = $CmdLine[1]
            Case Else
                MsgBox(0, "Error!", "Too many Parameters! " & UBound($CmdLine)-1, 5)
                Exit
        EndSelect
        
        ; Validate Process Extension - if it isn't an exe or msi then exit out because it can't run, therefore can't be watched.
        $ProcessExtension = StringRight($WatchProcess, 4)

        If $ProcessExtension = ".exe" Or $ProcessExtension = ".msi" Then 
            $ValidProcess = True
            $WatchProcess = FileGetShortName($WatchProcess) ; this guards agains the change when LongFileName.exe becomes LongFi~1.exe
        Else
            MsgBox(0, "Error!", "Invalid process extension! Must be either .exe or .msi! Currently " & $ProcessExtension, 10)
            Exit
        EndIf
    EndIf
EndFunc

Func DisplayProgress($ProcName)
    
    Local $tricky = False ; flag to indicate a process with the same name already exists, thus requiring tricky coding to work around.
    
    ; Need to check if there's more than one process with that name
    Local $avRET = _ProcessListProperties($ProcName) ; Generate an array of processes named $procname
    
    If $avRET[0][0] > 0 Then
        $tricky = True 
        Dim $atPID[UBound($avRET,1)] ; array of temporary Process Identifiers
        For $i = 1 to UBound($avRET,1)-1
            $atPID[$i] = $avRET[$i][3]
        Next
        $atPID[0] = UBound($atPID)
        _ArraySort($atPID, 0, 1)
    EndIf

    
    If ProcessWait($ProcName, 120) Then ; Wait until that exact processname is exists (listed within taskmanager). Wait 120 seconds at most.

        ProgressOn($Title & " Software Package", "Please be patient.", $msg)

        While ProcessExists($ProcName)

            For $i = 1 to 100 step 1
                sleep(15)
                ProgressSet($i)
                If Not ProcessExists($ProcName) Then ExitLoop
            Next
            
            If $tricky Then
                $avRET = _ProcessListProperties($ProcName) ; Generate an array of processes named $procname again
                _ArraySort($avRET)

                ; Tricky code required here.
                ; Needs to compare the Process Ids in the new array ($avRET), with the Process IDs in the temporary array ($atPID)
                ; If the arrays are identical, then exit loop.
                ; Else continue
                ; 
                    

            EndIf
        WEnd
        ProgressSet(100 , "Done", "Complete")
        sleep(500)
        ProgressOff()
    Else
        MsgBox(0, "Timed out!", "Script timed out waiting for " & $ProcName, 5)
    EndIf
    
EndFunc

#region - process listing array stuff

;===============================================================================
;
; 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, if empty or not
;             given lists all processes.
;           (optional) $sComputer - remote computer to get list from
; 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
;             ...
;             [n][0] thru [n][6] - 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
; Notes:            If a numeric 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.
;===============================================================================
Func _ProcessListProperties($Process = "", $sComputer = ".")
    Local $sUserName, $sMsg, $sUserDomain, $avProcs
    If $Process = "" Then
        $avProcs = ProcessList()
    Else
        $avProcs = ProcessList($Process)
    EndIf
   
    ; Return for no matches
    If $avProcs[0][0] = 0 Then Return $avProcs
   
    ; ReDim array for additional property columns
    ReDim $avProcs[$avProcs[0][0] + 1][7]
   
    ; Connect to WMI and get process objects
    $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2")
    If IsObj($oWMI) Then
        ; Get collection of all processes from Win32_Process
        $colProcs = $oWMI.ExecQuery ("select * from win32_process")
        If IsObj($colProcs) Then
            ; For each process...
            For $oProc In $colProcs
                ; Find it in the array
                For $n = 1 To $avProcs[0][0]
                    If $avProcs[$n][1] = $oProc.ProcessId Then
                       
                        ; [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
                       
                        ExitLoop
                    EndIf
                Next
            Next
        Else
            SetError(2) ; Error getting process collection from WMI
        EndIf
       
        ; 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
        $oRefresher = ObjCreate("WbemScripting.SWbemRefresher")
        $colProcs = $oRefresher.AddEnum ($oWMI, "Win32_PerfFormattedData_PerfProc_Process").objectSet
        $oRefresher.Refresh
        Sleep(1000)
        $oRefresher.Refresh
        For $oProc In $colProcs
            ; Find it in the array
            For $n = 1 To $avProcs[0][0]
                If $avProcs[$n][1] = $oProc.IDProcess Then
                    $avProcs[$n][6] = $oProc.PercentProcessorTime
                    ExitLoop
                EndIf
            Next
        Next
    Else
        SetError(1) ; Error connecting to WMI
    EndIf
   
    ; Return array
    Return $avProcs
EndFunc   ;==>_ProcessListProperties
#endregion


_GetParams()
DisplayProgress($WatchProcess)

Exit

Share this post


Link to post
Share on other sites

Next step is the memory usage... any more hints?

The topic of process memory usage came up again and multiple solutions were found. See topic: Some stupid problem with probably easy solution

At least two other methods are also discussed there, but this is an update of my function, now providing process memory usage in the return array at [n][7]:

#include <array.au3> ; for _ArrayDisplay()

$avRET = _ProcessListProperties()
_ArrayDisplay($avRET, "Debug: $avProcs, @error = " & @error)


;===============================================================================
; 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
;             ...
;             [n][0] thru [n][7] - 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
; Notes:            If a numeric 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.
;===============================================================================
Func _ProcessListProperties($Process = "", $sComputer = ".")
    Local $sUserName, $sMsg, $sUserDomain, $avProcs
    If $Process = "" Then
        $avProcs = ProcessList()
    Else
        $avProcs = ProcessList($Process)
    EndIf

    ; Return for no matches
    If $avProcs[0][0] = 0 Then Return $avProcs

    ; ReDim array for additional property columns
    ReDim $avProcs[$avProcs[0][0] + 1][8]

    ; Connect to WMI and get process objects
    $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2")
    If IsObj($oWMI) Then
        ; Get collection of all processes from Win32_Process
        $colProcs = $oWMI.ExecQuery ("select * from win32_process")
        If IsObj($colProcs) Then
            ; For each process...
            For $oProc In $colProcs
                ; Find it in the array
                For $n = 1 To $avProcs[0][0]
                    If $avProcs[$n][1] = $oProc.ProcessId Then

                        ; [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

                        ExitLoop
                    EndIf
                Next
            Next
        Else
            SetError(2) ; Error getting process collection from WMI
        EndIf

        ; 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(10)
        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
                    $avProcs[$n][6] = $oProc.PercentProcessorTime
                    $avProcs[$n][7] = $oProc.WorkingSet
                    ExitLoop
                EndIf
            Next
        Next
    Else
        SetError(1) ; Error connecting to WMI
    EndIf

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

Cheers!

:)


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

#13 ·  Posted (edited)

.......... this is an update of my function

Very useful, thanks PsaltyDS.

If you're interested in that have you seen Alzo Process Management? It's worth a look.

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Very useful, thanks PsaltyDS.

If you're interested in that have you seen Alzo Process Management? It's worth a look.

It certainly is. Doesn't currently show per-process memory or percent CPU time usage, but probably will soon.

:)


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

I have updated the _ProcessListProperties() function with a tweak to prevent a COM error when a process is closed while the function is running. This is the patched version:

;===============================================================================
; 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
;             ...
;             [n][0] thru [n][7] - 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
; Notes:            If a numeric 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.
;===============================================================================
Func _ProcessListProperties($Process = "", $sComputer = ".")
    Local $sUserName, $sMsg, $sUserDomain, $avProcs, $sObjName
    If $Process = "" Then
        $avProcs = ProcessList()
    Else
        $avProcs = ProcessList($Process)
    EndIf

    ; Return for no matches
    If $avProcs[0][0] = 0 Then Return $avProcs

    ; ReDim array for additional property columns
    ReDim $avProcs[$avProcs[0][0] + 1][8]

    ; Connect to WMI and get process objects
    $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\cimv2")
    If IsObj($oWMI) Then
        ; Get collection of all processes from Win32_Process
        $colProcs = $oWMI.ExecQuery ("select * from win32_process")
        If IsObj($colProcs) Then
            ; For each process...
            For $oProc In $colProcs
                $sObjName = ObjName($oProc, 3) ; 3 = ProgID
                If @error Then ContinueLoop ; Skip if process no longer exists
                ; Find it in the array
                For $n = 1 To $avProcs[0][0]
                    If $avProcs[$n][1] = $oProc.ProcessId Then

                        ; [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

                        ExitLoop
                    EndIf
                Next
            Next
        Else
            SetError(2) ; Error getting process collection from WMI
        EndIf

        ; 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(10)
        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
                    $avProcs[$n][6] = $oProc.PercentProcessorTime
                    $avProcs[$n][7] = $oProc.WorkingSet
                    ExitLoop
                EndIf
            Next
        Next
    Else
        SetError(1) ; Error connecting to WMI
    EndIf

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

Cheers!

:P


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  
Followers 0