WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

DllCall Information

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Get Process Times


<HR>
; GetProcessTimes_UDF.wbt
; 32-bit
;
; UDF library to obtain a process' times using a kernel mode API function.
;
; The process extender is used to open a handle to a process using a PID value,
; but we could easily eliminate that requirement by calling a Win32 API function
; via DllCall().  The shortcut of using the tOpenProc() function is used since it
; is likely that the process extender is already being used to get an enumerated
; list of PID values.
;
; Rigorous error handling has not been implemented in this UDF.
;
; The process termination time will be an empty string for a process that is still running
;
; The kernel & user mode times need to be calculated using the huge math extender since
; they are really unsigned 64 bit integer values.  The little arithmetic trick used to
; handle the separate Hi & Lo DWORD values that compose a file system time is introducing
; a slight bit of numerical error in the final results.  A file system time is measured in
; 100 nanosecond intervals, either as an absolute time using an epoch of 1/1/1601 00:00:00,
; or as a relative time simply measured in 100 ns units.


#DefineFunction udfGetProcessTimes(nPID)

If (nPID == '')
  nPID = DllCall('KERNEL32.DLL',long:'GetCurrentProcessId')
EndIf

If (!IsInt(nPID)) Then Return 0

; Set up the constants & binary buffers needed to do the job.

nProcInfoBufSize = 4 * 8
hProcInfoBuf = BinaryAlloc(nProcInfoBufSize)

nFileTimeBufSize = 2 * 4
hFileTimeBuf = BinaryAlloc(nFileTimeBufSize)

nSystemTimeBufSize = 8 * 2
hSystemTimeBuf = BinaryAlloc(nSystemTimeBufSize)

; This is the particular information class value that we're using.

ProcessTimes = 4

; Open a handle to the process for query information access.

hProc = tOpenProc(nPID,2)

Result = DllCall('NTDLL.DLL',long:'ZwQueryInformationProcess',long:hProc,long:ProcessTimes,lpbinary:hProcInfoBuf,long:nProcInfoBufSize,lpnull)

BinaryEodSet(hProcInfoBuf,nProcInfoBufSize)

TimeList = ArrDimension(4)

tCloseProc(hProc)
hProc = 0

; Get the process creation time.

BinaryCopy(hFileTimeBuf,0,hProcInfoBuf,0,nFileTimeBufSize)
Result = DllCall('KERNEL32.DLL',long:'FileTimeToSystemTime',lpbinary:hFileTimeBuf,lpbinary:hSystemTimeBuf)
BinaryEodSet(hSystemTimeBuf,nSystemTimeBufSize)
If (Result != 0)
  TimeList[0] = ''
  TimeList[0] = StrCat(TimeList[0],StrFixLeft(BinaryPeek2(hSystemTimeBuf,0),'0',4))
  TimeList[0] = StrCat(TimeList[0],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,2),'0',2))
  TimeList[0] = StrCat(TimeList[0],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,6),'0',2))
  TimeList[0] = StrCat(TimeList[0],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,8),'0',2))
  TimeList[0] = StrCat(TimeList[0],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,10),'0',2))
  TimeList[0] = StrCat(TimeList[0],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,12),'0',2))
Else
  TimeList[i] = ''
EndIf

; Get the process termination time.

BinaryCopy(hFileTimeBuf,0,hProcInfoBuf,8,nFileTimeBufSize)

If (BinaryPeek4(hFileTimeBuf,0) == 0 && BinaryPeek4(hFileTimeBuf,4) == 0)
  TimeList[1] = ''
Else
  Result = DllCall('KERNEL32.DLL',long:'FileTimeToSystemTime',lpbinary:hFileTimeBuf,lpbinary:hSystemTimeBuf)
  BinaryEodSet(hSystemTimeBuf,nSystemTimeBufSize)
  If (Result != 0)
    TimeList[1] = ''
    TimeList[1] = StrCat(TimeList[1],StrFixLeft(BinaryPeek2(hSystemTimeBuf,0),'0',4))
    TimeList[1] = StrCat(TimeList[1],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,2),'0',2))
    TimeList[1] = StrCat(TimeList[1],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,6),'0',2))
    TimeList[1] = StrCat(TimeList[1],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,8),'0',2))
    TimeList[1] = StrCat(TimeList[1],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,10),'0',2))
    TimeList[1] = StrCat(TimeList[1],':',StrFixLeft(BinaryPeek2(hSystemTimeBuf,12),'0',2))
  Else
    TimeList[1] = ''
  EndIf
EndIf

TimeLoDW = BinaryPeek4(hProcInfoBuf,16)
TimeHiDW = BinaryPeek4(hProcInfoBuf,20)

TimeHiDW = (TimeHiDW * 0.0000001) * 2.0**32
TimeLoDW = (TimeLoDW * 0.0000001)

TimeList[2] = TimeHiDW + TimeLoDW

TimeLoDW = BinaryPeek4(hProcInfoBuf,24)
TimeHiDW = BinaryPeek4(hProcInfoBuf,28)

TimeHiDW = (TimeHiDW * 0.0000001) * 2.0**32
TimeLoDW = (TimeLoDW * 0.0000001)

TimeList[3] = TimeHiDW + TimeLoDW

; Free up the buffers we used.

hProcInfoBuf = BinaryFree(hProcInfoBuf)
hFileTimeBuf = BinaryFree(hFileTimeBuf)
hSystemTimeBuf = BinaryFree(hSystemTimeBuf)


Return TimeList

#EndFunction



; This UDF requires the process extender

AddExtender('wwprc44I.dll')

Title01 = 'Get Process Times'

; the PID variable must be a valid PID [Process IDentifier] value.  In this case, we will be sneaky
; and rely on the default behavior of the UDF, which is coded to substitute our own PID value if
; the PID parameter is an empty string.

PID = ''

Result = udfGetProcessTimes(PID)

If (VarType(Result) == 256)
  TempMsg = StrCat('Process Create Time (UTC) = "',Result[0],'"')
  TempMsg = StrCat(TempMsg,@CRLF,'Process Exit Time (UTC) = "',Result[1],'"')
  TempMsg = StrCat(TempMsg,@CRLF,'Process Kernel Time (seconds) = ',Result[2])
  TempMsg = StrCat(TempMsg,@CRLF,'Process User Time (seconds) = ',Result[3])
  Message(Title01,TempMsg)
Else
  Message(Title01,'Errror!  Result is not an array.')
EndIf



Exit


Article ID:   W17405
File Created: 2013:04:01:09:14:56
Last Updated: 2013:04:01:09:14:56