Jump to content

ProcessListDiff See what process have stopped or started in between calls to ProcessList()

Recommended Posts


Made this from a question in Help and Support

#include <Array.au3>
$aPreProcesses = ProcessList()

$iNotepad = ShellExecute("notepad.exe")
MsgBox(0, "Run or Exit Some Applications", "")

_ArrayDisplay(_Processlist_Diff($aPreProcesses, ProcessList()))

;With Process Name & List Containing PID
_ArrayDisplay(_Processlist_Diff($aPreProcesses, ProcessList(), True))

;Returns Array of [PID]
;If bExtended = true ;Returns Array [Processname, PID, List# Containing PID]
Func _Processlist_Diff(Const ByRef $aProcList0, Const ByRef $aProcList1, $bExtended = False)
    ; Check arrays
    Local $iRowsP1 = UBound($aProcList0, $UBOUND_ROWS) - 1
    If $iRowsP1 <= 0 Then Return SetError(1, 0, 0)
    If UBound($aProcList0, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(2, 0, 0)

    $iRowsP2 = UBound($aProcList1, $UBOUND_ROWS) - 1
    If $iRowsP2 <= 0 Then Return SetError(3, 0, 0)
    If UBound($aProcList1, $UBOUND_DIMENSIONS) <> 2 Then Return SetError(4, 0, 0)

    ; Create error handler
    ObjEvent("AutoIt.Error", "__Processlist_Diff_AutoErrFunc")
    ; Create dictionary
    Local $oDictionary = ObjCreate("Scripting.Dictionary")
    ; Set case sensitivity
    $oDictionary.CompareMode = 0 ;Binary Compare
    ; Add elements to dictionary
    Local $vKey, $vElem, $bCOMError = False
    For $i = 0 To $iRowsP1 + $iRowsP2 - 1
        If $iRowsP1 > 0 Then
            $vElem = "#PL0#" & $aProcList0[$iRowsP1][0]
            $vKey = $aProcList0[$iRowsP1][1]
            $iRowsP1 -= 1
            $vElem = "#PL1#" & $aProcList1[$iRowsP2][0]
            $vKey = $aProcList1[$iRowsP2][1]

            $iRowsP2 -= 1

        If $oDictionary.Exists($vKey) Then
            ;ConsoleWrite("DUPE PID " & $vElem & @CRLF)
            ; Add Key $ Element
            $oDictionary.Item($vKey) = $vElem

        If @error Then
            $bCOMError = True ; Failed with an Int64, Ptr or Binary datatype
    ; Create return array
    Local $aValues, $j = 0
    If $bCOMError Then ; Mismatch Int32/64
        Return SetError(5, 0, 0)
    ElseIf $bExtended Then
        Local $aValues[$oDictionary.Count][3]
        For $vKey In $oDictionary.Keys()
            $vElem = $oDictionary.Item($vKey)
            $aValues[$j][0] = StringTrimLeft($vElem, 5)
            $aValues[$j][1] = $vKey
            ; Check which list contains PID
            If StringLeft($vElem, 5) = "#PL0#" Then
                $aValues[$j][2] = 0
                $aValues[$j][2] = 1

            $j += 1
    Else ;Only PID
        ; Only need to list Keys
        $aValues = $oDictionary.Keys()
    $oDictionary.RemoveAll ;would be cleaned up anyway..
    ; Return array
    Return $aValues
EndFunc   ;==>_Processlist_Diff

Func __Processlist_Diff_AutoErrFunc()
    ; Do nothing special, just check @error after suspect functions.
EndFunc   ;==>__Processlist_Diff_AutoErrFunc

The bExtended = True Returns Array [Processname. PID, List# Containing PID] for each PID that isn't in both lists

If bExtended = False (Default) Return is just an array of [PID] 

Edited by Bilgus
Made Extended part of the function instead of two separate functions; Made Status Instead return which list it was found in
  • Like 1

Share this post

Link to post
Share on other sites

I've changed the function a bit..

First off instead of a textual status extended mode returns the number of the list the PID was found in

I think this cuts down on confusion since now you can add the arrays in any order with an unambiguous result.

Second I've merged the [PID] only version with the extended version using $bExtended to get the latter behavior \


I did some testing between user accounts and it seems that ProcessList() does indeed get processes from all users

Here is the original H&S post so you can see how it evolved


Edited by Bilgus

Share this post

Link to post
Share on other sites

This could be very useful when testing 

  • Thanks 1

My resources are limited. You must ask the right questions


Share this post

Link to post
Share on other sites

Thanks, OP gets all the credit for that but, I thought it pretty interesting myself

I think it would be especially useful if combined with Enum[Modules/Threads/Windows]

  • Like 1

Share this post

Link to post
Share on other sites

Sure But it appears it happens more often than I figured so..  thats a limitation of this method 

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

  • Similar Content

    • careca
      By careca
      That's it, self explanatory, it used to work and now be it, a variable assigned to a process name, or the pname itself, or a macro, or the full path + pname, always zero.
      Any idea why?
      $aProcessList = ProcessList(@AutoItExe) ;@AutoItPID @AutoItExe @ScriptFullPath MsgBox(64, 'ProcessList', $aProcessList[0][0])