To terminate a process for which you know the process handle, you can use function TerminateProcess.
If you don't know the process handle but the process identifier, you can get the handle by calling OpenProcess first.
DEFINE INPUT PARAMETER ProcessId AS INTEGER NO-UNDO. DEFINE VARIABLE ProcessHandle AS INTEGER NO-UNDO. DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO. RUN OpenProcess ({&PROCESS_TERMINATE}, 0, ProcessId, OUTPUT ProcessHandle). IF ProcessHandle NE 0 THEN DO: RUN TerminateProcess (ProcessHandle, 0, OUTPUT ReturnValue). RUN CloseHandle(ProcessHandle, OUTPUT ReturnValue). END.
Definitions used in this procedure:
&GLOB PROCESS_TERMINATE 1 PROCEDURE OpenProcess EXTERNAL "kernel32" : 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" : DEFINE INPUT PARAMETER hObject AS LONG. DEFINE RETURN PARAMETER ReturnValue AS LONG. END PROCEDURE. PROCEDURE TerminateProcess EXTERNAL "kernel32" : DEFINE INPUT PARAMETER hProcess AS LONG. DEFINE INPUT PARAMETER uExitCode AS LONG. DEFINE RETURN PARAMETER retval AS LONG. END PROCEDURE.
TerminateProcess is guaranteed to free all resources allocated by the process.
But, similar to "kill -9" in Unix, the process will not get the opportunity to perform any of its shutdown code. Examples of shutdown code can be: writing "recent actions" in registry, notifying other processes, saving data etc.
Because of this, TerminateProcess should only be used as an emergency measure.
A more cautious way to terminate a process would be to find all its top-level windows and send a WM_CLOSE message to each of those windows. If this does not succeed within some time interval ("not responding") you can still use TerminateProcess.
An example of how to do this is on page terminate a process gently