GetProcessTimes

sourcecode by Michael Rüsweg-Gilbert

Function GetProcessTimes works on Windows NT only.
GetProcessTimes obtains timing information about a specified process: the creation time, exit time, kernel time and user time. All these are returned as FILETIME structures (a 64 bit count of 100-nanosecond units).
Creation time and exit time are expressed as time elapsed since midnight January 1, 1601 (UTC). Function FileTimeToSystemTime converts this to system time - which may also be UTC.
Function FileTimeToLocalFileTime can be called prior to FileTimeToSystemTime if you want the output to be displayed in local time.
Kernel time and user time are amounts of time: the FILETIME structures will contain the amount of 100 nanosecond units (ten million units is one second).
This example uses GetProcessTimes for the current (Progress) process. The exit time is null or random because the current process did not exit yet.

/* -----------------------------------------------------------
// File: tst_procTime.p 
// Desc: query the process-times of the current process
// 
// Parm: --- 
// 
// 
// Author: Michael Rüsweg-Gilbert
// Created: 20. Sept. 1999
-------------------------------------------------------------- */
DEFINE VARIABLE RetVal           AS INTEGER    NO-UNDO. 
DEFINE VARIABLE me_Crea          AS MEMPTR NO-UNDO. 
DEFINE VARIABLE me_Exit          AS MEMPTR NO-UNDO. 
DEFINE VARIABLE me_Kern          AS MEMPTR NO-UNDO. 
DEFINE VARIABLE me_User          AS MEMPTR NO-UNDO. 
DEFINE VARIABLE hProc            AS INTEGER    NO-UNDO. 
DEFINE VARIABLE PID              AS INTEGER    NO-UNDO.
 
&GLOB TRUE  1
&GLOB FALSE 0
&GLOB PROCESS_ALL_ACCESS 2035711   /* 0x0F0000 | 0x100000 | 0x000FFF */
 
/* Convert FileTime into a readable LocalTime-String */
FUNCTION proTimeString RETURNS CHAR
( ip_filetime AS MEMPTR):
DEFINE VARIABLE tmp_sysTime AS MEMPTR NO-UNDO.
DEFINE VARIABLE Ret         AS INTEGER    NO-UNDO.
DEFINE VARIABLE cTime       AS CHARACTER   NO-UNDO INIT ?.
 
    SET-SIZE(tmp_sysTime) = 16.
    /* Convert UTC-Time to Local Time */
    RUN FileTimeToSystemTime ( INPUT ip_filetime,
                               OUTPUT tmp_systime,
                               OUTPUT Ret ).
    IF Ret = {&TRUE} THEN DO:
       /* a DAY.MONTH.YEAR HOUR:MINUTE:SECOND-string */
       cTime = STRING(GET-SHORT(tmp_sysTime,  7)) + "." +
               STRING(GET-SHORT(tmp_sysTime,  3)) + "." +
               STRING(GET-SHORT(tmp_sysTime,  1)) + " " +
               STRING(GET-SHORT(tmp_sysTime,  9)) + ":" +
               STRING(GET-SHORT(tmp_sysTime, 11)) + ":" +
               STRING(GET-SHORT(tmp_sysTime, 13)).
    END.
 
    SET-SIZE(tmp_sysTime) = 0.
 
    IF cTime = ?
       THEN RETURN "Error in FileTimeToSystemTime; Ret=" + STRING(Ret).
       ELSE RETURN cTime.
END FUNCTION.
 
 
/* first obtain the current Process Token (add Debug rights) */
RUN GetCurrentProcessId(OUTPUT PID).
 
RUN OpenProcess ( {&Process_All_Access},
                  0,
                  PID,
                  OUTPUT hProc).
IF hProc LT 1 THEN DO:
    MESSAGE "Can't open current PID" PID
            VIEW-AS ALERT-BOX INFO BUTTONS OK.
    RETURN.
END.
 
HProc0:
DO:
 
    SET-SIZE(me_Crea) =  8.
    SET-SIZE(me_Exit) =  8.
    SET-SIZE(me_Kern) =  8.
    SET-SIZE(me_User) =  8.
 
    RUN GetProcessTimes ( hProc,
                          me_Crea,
                          me_Exit,
                          me_Kern,
                          me_User,
                          OUTPUT RetVal).
    IF RetVal NE {&TRUE} THEN DO:
        MESSAGE "GetProcessTimes returned" RetVal
           VIEW-AS ALERT-BOX.
        LEAVE.
    END.
 
    MESSAGE "Creation Time: " ProTimeString(me_Crea) SKIP
            "    Exit Time: " ProTimeString(me_Exit) SKIP
            "  Kernel Time: " ProTimeString(me_Kern) SKIP
            "    User Time: " ProTimeString(me_User)
       VIEW-AS ALERT-BOX.
 
 
END.
 
SET-SIZE(me_Crea) =  0.
SET-SIZE(me_Exit) =  0.
SET-SIZE(me_Kern) =  0.
SET-SIZE(me_User) =  0.
 
RUN CloseHandle ( hProc, OUTPUT RetVal).
 
RETURN.
 
 
PROCEDURE CloseHandle EXTERNAL "kernel32":
  DEFINE INPUT  PARAMETER hObject         AS LONG .
  DEFINE RETURN PARAMETER retval          AS LONG .
END PROCEDURE.
 
PROCEDURE GetCurrentProcessId EXTERNAL "kernel32":
  DEFINE RETURN PARAMETER PID             AS LONG .
END PROCEDURE.
 
PROCEDURE GetLastError EXTERNAL "kernel32":
  DEFINE RETURN PARAMETER dwError         AS LONG .
END PROCEDURE.
 
PROCEDURE OpenProcess EXTERNAL "kernel32.dll" :
  DEFINE INPUT  PARAMETER dwDesiredAccess AS LONG.
  DEFINE INPUT  PARAMETER bInheritHandle  AS LONG.
  DEFINE INPUT  PARAMETER dwProcessId     AS LONG.
  DEFINE RETURN PARAMETER hProcess        AS LONG.
END PROCEDURE.
 
PROCEDURE GetProcessTimes EXTERNAL "kernel32.dll" :
  DEFINE INPUT  PARAMETER hProcess        AS LONG.
  DEFINE INPUT  PARAMETER lpCreationTime  AS MEMPTR. /* FILETIME */
  DEFINE INPUT  PARAMETER lpExitTime      AS MEMPTR. /* FILETIME */
  DEFINE INPUT  PARAMETER lpKernelTime    AS MEMPTR. /* FILETIME */
  DEFINE INPUT  PARAMETER lpUserTime      AS MEMPTR. /* FILETIME */
  DEFINE RETURN PARAMETER RetBool         AS LONG.
END PROCEDURE.
 
PROCEDURE FileTimeToSystemTime EXTERNAL "kernel32.dll":
  DEFINE INPUT  PARAMETER lpFileTime      AS MEMPTR. /* L = 8 */
  DEFINE OUTPUT PARAMETER lpSystemTime    AS MEMPTR. /* L = 16 */
  DEFINE RETURN PARAMETER retBool         AS LONG.   /* = 0, if failure */
END PROCEDURE.