Jump to content

How to Know PID in this case


Go to solution Solved by Ascend4nt,

Recommended Posts

well, f*k me, I guess I like a good challenge.  Here's a UDF for finding processes that started after a given time point:

; ========================================================================================================
; <_ProcessListAfterTimePoint.au3>
;
; Functions to get an array of processes that started after a given time point
; Example included displays array of processes
;
; Functions:
;    _WinTime_GetSystemTimeAsLocalFileTime()  ; Gets current time as 64-bit FILETIME (_WinTimeFunctions UDF)
;    _ProcessListAfterTime()    ; Gets list of processes after a certain timepoint (as FILETIME)
;
; Author: Ascend4nt
; ========================================================================================================
#include <WinAPI.au3>    ; ProcessOpen/CloseHandle

; ==============================================================================================
; Func _WinTime_GetSystemTimeAsLocalFileTime()
;
; Function to grab the current system time as 64bit Local FileTime (not UTC)
; (from _WinTimeFunctions UDF)
;
; Return:
;    Success: 64-bit value representing the UTC-based FileTime
;    Failure: -1, with @error set:
;        @error = 2 = DLL Call error, @extended = actual DLLCall error code
;
; Author: Ascend4nt
; ==============================================================================================
Func _WinTime_GetSystemTimeAsLocalFileTime()
    Local $aRet=DllCall("kernel32.dll","none","GetSystemTimeAsFileTime","uint64*",0)
    If @error Then Return SetError(2,@error,-1)
    Return $aRet[1]
EndFunc

; ==============================================================================================
; Func _ProcessListAfterTime($nSysTime, $vProcFilter = "")
;
; Returns an array of Processes that started after a given time point (as FILETIME)
;
; $nSysTime = a 64-bit FILETIME value (see GetSystemTimeAsFileTime) to use
;             as the starting point
;
; $vProcFilter = Process name filter ("calc.exe") or "" for ALL processes
;
; Returns:
;  Success: An array of processes in the same form as ProcessList:
;    [0][0] = # of processes
;    [i][0] = Process name
;    [i][1] = Process ID #
;
; Failure: "" with @error set (only happens if ProcessList() itself fails)
;
;
; Author: Ascend4nt
; ==============================================================================================

Func _ProcessListAfterTime($nSysTime, $vProcFilter = "")
    Local $aProcList, $aFoundList, $nFound
    Local $iAccess, $hProcess

    If $vProcFilter = "" Then
        $aProcList = ProcessList()
    Else
        $aProcList = ProcessList($vProcFilter)
    EndIf
    If @error Then Return SetError(@error,0,"")

    ; XP, XPe, 2000, or 2003? - Affects process access requirement
    If StringRegExp(@OSVersion,"_(XP|200(0|3))") Then
        $iAccess = 0x0400    ; PROCESS_QUERY_INFORMATION
    Else
        $iAccess = 0x1000    ; PROCESS_QUERY_LIMITED_INFORMATION
    EndIf

    Dim $aFoundList[$aProcList[0][0]+1][2]
    $nFound = 0

    For $i = 1 To $aProcList[0][0]
        $hProcess = _WinAPI_OpenProcess($iAccess, False, $aProcList[$i][1])
        $aRet = DllCall("kernel32.dll", "bool", "GetProcessTimes", "handle", $hProcess, "uint64*", 0, "uint64*", 0, "uint64*", 0, "uint64*", 0)
        If Not @error And $aRet[0] And $aRet[2] > $nSysTime Then
            ConsoleWrite("Found process that started after timepoint: " & $aProcList[$i][0]&", PID #" & $aProcList[$i][1] & @CRLF)
            $nFound += 1
            $aFoundList[$nFound][0] = $aProcList[$i][0]
            $aFoundList[$nFound][1] = $aProcList[$i][1]
        EndIf
        _WinAPI_CloseHandle($hProcess)
    Next
    $aFoundList[0][0] = $nFound

    ReDim $aFoundList[$nFound + 1][2]
    Return $aFoundList
EndFunc


; --- EXAMPLE USAGE ---

#include <Array.au3>
Local $nSysTime, $aProcList

$nSysTime = _WinTime_GetSystemTimeAsLocalFileTime()
Run("calc.exe")
Run("notepad.exe")
Sleep(500)

$aProcList = _ProcessListAfterTime($nSysTime)
_ArrayDisplay($aProcList, "Processes that started after start point")
 

In michaelslamet's case, call it like _ProcessListAfterTime($nSysTime, "iexplore.exe").

 

I'm happy to know that my post give you a challenge you like :*

I try the above sample, _ArrayDisplay and Console only tell that the process is Notepad.exe. Calc.exe is run, but there is no calc.exe process after I run the code.

--> Press Ctrl+Alt+F5 to Restart or Ctrl+Break to Stop

Found process that started after timepoint: notepad.exe, PID #6724

I even try to change Sleep(500) to Sleep(5000) but same result.

Something must be wrong here.

Link to comment
Share on other sites

I'm happy to know that my post give you a challenge you like :*

I try the above sample, _ArrayDisplay and Console only tell that the process is Notepad.exe. Calc.exe is run, but there is no calc.exe process after I run the code.

--> Press Ctrl+Alt+F5 to Restart or Ctrl+Break to Stop

Found process that started after timepoint: notepad.exe, PID #6724

I even try to change Sleep(500) to Sleep(5000) but same result.

Something must be wrong here.

michaelslamet,

It should work properly if Run("calc.exe") opens up a process that isn't closed before the _ProcessListAfterTime() is called.  There is possibility of failure if the process starts within a 100-nanosecond interval between getting the time and starting the new process - but that's doubtful even on the fastest system.  Also, there is a possibility that a process can't be opened using OpenProcess, in which case it wouldn't be reported.  However, calc.exe and notepad.exe are both simple Windows apps that wouldn't have access problems.

However, if calc.exe is redirected to another executable in the registry, or closed perhaps if only one instance is allowed (for whatever reason), then you will possibly not see it in the list.

Just to be thorough, put a Sleep(10) after getting $nSysTime and before the first Run(). Close all open notepad and calculator instances, and make certain both the calculator and notepad pop up as NEW processes within the time frame we Sleep for (500 ms or 5000 if you like). One more thing to try is to put #RequireAdmin at the top of the script, but that really should not make any difference with normal processes, and even most elevated processes.

*edit: and make sure NOT to close calculator or notepad before the script completes!

Edited by Ascend4nt
Link to comment
Share on other sites

michaelslamet,

It should work properly if Run("calc.exe") opens up a process that isn't closed before the _ProcessListAfterTime() is called.  There is possibility of failure if the process starts within a 100-nanosecond interval between getting the time and starting the new process - but that's doubtful even on the fastest system.  Also, there is a possibility that a process can't be opened using OpenProcess, in which case it wouldn't be reported.  However, calc.exe and notepad.exe are both simple Windows apps that wouldn't have access problems.

However, if calc.exe is redirected to another executable in the registry, or closed perhaps if only one instance is allowed (for whatever reason), then you will possibly not see it in the list.

Just to be thorough, put a Sleep(10) after getting $nSysTime and before the first Run(). Close all open notepad and calculator instances, and make certain both the calculator and notepad pop up as NEW processes within the time frame we Sleep for (500 ms or 5000 if you like). One more thing to try is to put #RequireAdmin at the top of the script, but that really should not make any difference with normal processes, and even most elevated processes.

*edit: and make sure NOT to close calculator or notepad before the script completes!

 

Hi Ascent4nt,

Put Sleep(10) after getting $nSysTime solve it :)

Just now, before put the Sleep(10), I run it few time.

Firsttime it display both processes correctly.

Second and thirdtime it only report notepad.exe

Thank you very much for your help :)

Link to comment
Share on other sites

Interesting, and quite unusual really. The function relies on 'FILETIME ' which is based on 100-nanosecond intervals.  I'm curious why a sleep would be necessary, but it could be some quirk with how Windows works.  According to the MSDN "File Times (Windows)"  article, there are cases with files that may not see changes for 10ms on FAT and 1 hour on NTFS (base on update interval), but there's been nothing about process times.  Oh well, 10ms is not a big deal.. I'll update the code with that Sleep for those 'just in case' moments.

*edit: Oddly enough, that Sleep(10) helps my results too - I'm able to reduce the time between the Run() and the process collection. Interesting!

Edited by Ascend4nt
Link to comment
Share on other sites

Interesting, and quite unusual really. The function relies on 'FILETIME ' which is based on 100-nanosecond intervals.  I'm curious why a sleep would be necessary, but it could be some quirk with how Windows works.  According to the MSDN "File Times (Windows)"  article, there are cases with files that may not see changes for 10ms on FAT and 1 hour on NTFS (base on update interval), but there's been nothing about process times.  Oh well, 10ms is not a big deal.. I'll update the code with that Sleep for those 'just in case' moments.

*edit: Oddly enough, that Sleep(10) helps my results too - I'm able to reduce the time between the Run() and the process collection. Interesting!

 

Yes, sleep(10) is not a big deal.

I'm happy to know that my noob thread make you interested :geek:

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...