This procedure can be used to show a list of all running processes, for example to see if Netscape.exe is running. The process indentifier (pid) can be used for getting additional information about the process, or for terminating the process.
This method uses the psapi.dll which only works on NT (and Windows 2000 etc). On Windows 95 or Windows 98 you can not use psapi.dll, instead you can use the much nicer CreateToolhelp32 functions.
To check if you are running Windows NT4.0 see page: which version of Windows is running.
FUNCTION GetProcessName RETURNS CHARACTER (INPUT PID AS INTEGER) : DEFINE VARIABLE hProcess AS INTEGER NO-UNDO. DEFINE VARIABLE cbNeeded AS INTEGER NO-UNDO. DEFINE VARIABLE lphMod AS MEMPTR NO-UNDO. DEFINE VARIABLE szProcessName AS CHARACTER NO-UNDO. DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO. /* OpenProcess returns a handle (hProcess), needed for querying info about the process */ RUN OpenProcess ( {&PROCESS_QUERY_INFORMATION} + {&PROCESS_VM_READ}, 0, PID, OUTPUT hProcess). /* some system processes can not be queried, like "System" and "System Idle Process" and "csrss.exe". ProcessName will be initialized to [unknown] for these processes: */ szProcessName = "[unknown]" + FILL(" ", {&MAX_PATH}). IF hProcess NE 0 THEN DO: /* EnumProcessModules fills an array of module handles */ /* The first module handle is a handle to the main module, and that's the only handle you need */ SET-SIZE (lphMod) = 4. /* need only one hMod */ RUN EnumProcessModules ( hProcess, GET-POINTER-VALUE(lphMod), GET-SIZE(lphMod), OUTPUT cbNeeded, OUTPUT ReturnValue). IF ReturnValue NE 0 THEN DO: /* GetModuleBaseNameA returns the name of a module. Because this module is the main module, it's also considered to be the name of the process */ RUN GetModuleBaseNameA (hProcess, GET-LONG(lphMod,1), OUTPUT szProcessName, LENGTH(szProcessName), OUTPUT ReturnValue). /* ReturnValue is the number of returned bytes (chars): */ szProcessName = SUBSTRING(szProcessName,1,ReturnValue). SET-SIZE (lphMod) = 0. END. RUN CloseHandle ( hProcess, OUTPUT ReturnValue). END. RETURN TRIM(szProcessName). END FUNCTION. /* =============== TEST ================ */ DEFINE VARIABLE lpId AS MEMPTR NO-UNDO. DEFINE VARIABLE PID AS INTEGER NO-UNDO. DEFINE VARIABLE cbNeeded AS INTEGER NO-UNDO. DEFINE VARIABLE i AS INTEGER NO-UNDO. DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO. /* lpID is an array of PID's (Process Identifiers) */ SET-SIZE(lpId) = 1000. /* assume room for 250 pid's */ /* EnumProcesses fills an array of PID's */ RUN EnumProcesses (INPUT GET-POINTER-VALUE(lpId), INPUT GET-SIZE(lpID), OUTPUT cbNeeded, OUTPUT ReturnValue). DO i = 1 TO cbNeeded / 4 : PID = GET-LONG(lpID, 4 * (i - 1) + 1). /* display what you have found (for testing purposes) */ MESSAGE 'PID=' PID SKIP 'Name=' GetProcessName(PID) VIEW-AS ALERT-BOX. END. SET-SIZE(lpId) = 0.
Definitions used in this procedure:
&GLOB PROCESS_QUERY_INFORMATION 1024 &GLOB PROCESS_VM_READ 16 &GLOB MAX_PATH 260 PROCEDURE EnumProcesses EXTERNAL "psapi.dll" : DEFINE INPUT PARAMETER lpIdProcess AS LONG. DEFINE INPUT PARAMETER cb AS LONG. DEFINE OUTPUT PARAMETER cbNeeded AS LONG. DEFINE RETURN PARAMETER ReturnValue AS LONG. END PROCEDURE. PROCEDURE EnumProcessModules EXTERNAL "psapi.dll" : DEFINE INPUT PARAMETER hProcess AS LONG. DEFINE INPUT PARAMETER lphModule AS LONG. /* lp to array of module handles */ DEFINE INPUT PARAMETER cb AS LONG. DEFINE OUTPUT PARAMETER cbNeeded AS LONG. DEFINE RETURN PARAMETER ReturnValue AS LONG. END PROCEDURE. PROCEDURE GetModuleBaseNameA EXTERNAL "psapi.dll" : DEFINE INPUT PARAMETER hProcess AS LONG. DEFINE INPUT PARAMETER hModule AS LONG. DEFINE OUTPUT PARAMETER lpBaseName AS CHARACTER. DEFINE INPUT PARAMETER nSize AS LONG. DEFINE RETURN PARAMETER nReturnedSize 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 CloseHandle EXTERNAL "kernel32.dll" : DEFINE INPUT PARAMETER hObject AS LONG. DEFINE RETURN PARAMETER ReturnValue AS LONG. END PROCEDURE.