&GLOB PROCESS_QUERY_INFORMATION 1024 &GLOB PROCESS_VM_READ 16 &GLOB MAX_PATH 260 &GLOB TH32CS_SNAPPROCESS 2 &GLOB PROCESS_TERMINATE 1 DEFINE VARIABLE viPID AS INTEGER NO-UNDO. DEFINE VARIABLE ProcessHandle AS INTEGER NO-UNDO. 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. 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 CHAR. 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. FUNCTION GetProcessName RETURNS CHAR (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 CHAR 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. {inc/windows.i} FUNCTION WINGetVersion RETURNS CHARACTER () : /*----------------------------------------------------------------------------- Purpose: Calls the WINAPI function GetVersionExA to determine the version of the Windows operating system that is running on the machine. Notes: Returns "95" for Windows 95, "98" for Windows 98, "NT" for Windows NT Returns "undef" if unable to determine platform. ------------------------------------------------------------------------------*/ DEF VAR v_version-buf AS MEMPTR. DEF VAR v_platform-id AS INTEGER NO-UNDO. DEF VAR v_platform-desc AS CHAR NO-UNDO. DEF VAR v_major-version AS INTEGER NO-UNDO. DEF VAR v_minor-version AS INTEGER NO-UNDO. DEF VAR v_return-value AS INTEGER NO-UNDO. SET-SIZE(v_version-buf) = 148. PUT-LONG(v_version-buf,1) = 148. RUN GetVersionExA (INPUT GET-POINTER-VALUE(v_version-buf), OUTPUT v_return-value). v_platform-id = GET-LONG(v_version-buf,17). CASE v_platform-id: WHEN 1 THEN DO: v_minor-version = GET-BYTE(v_version-buf,15). v_major-version = GET-BYTE(v_version-buf,16). END. OTHERWISE DO: v_major-version = GET-LONG(v_version-buf,5). v_minor-version = GET-LONG(v_version-buf,9). END. END. CASE v_platform-id: WHEN 0 THEN v_platform-desc = "3.1". WHEN 1 THEN DO: IF v_minor-version EQ 0 THEN v_platform-desc = "95". ELSE IF v_minor-version GT 0 THEN v_platform-desc = "98". ELSE v_platform-desc = "undef". END. WHEN 2 THEN v_platform-desc = "NT". OTHERWISE v_platform-desc = "undef". END. SET-SIZE(v_version-buf) = 0. RETURN v_platform-desc. END FUNCTION. PROCEDURE GetVersionExA EXTERNAL {&KERNEL} : DEFINE INPUT PARAMETER lpVersionInfo AS LONG. DEFINE RETURN PARAMETER ReturnValue AS {&BOOL}. END PROCEDURE. PROCEDURE ListProcesses: DEFINE OUTPUT PARAMETER pAdobePID AS CHARACTER NO-UNDO. DEF VAR hSnapShot AS INTEGER NO-UNDO. DEF VAR lpPE AS MEMPTR NO-UNDO. /* PROCESSENTRY32 structure */ DEF VAR ReturnValue AS INTEGER NO-UNDO. DEF VAR list AS CHARACTER NO-UNDO INITIAL "Process-List:". /* Create and open SnapShot-list */ RUN CreateToolhelp32Snapshot({&TH32CS_SNAPPROCESS}, 0, OUTPUT hSnapShot). IF hSnapShot = -1 THEN RETURN. /* init buffer for lpPE */ SET-SIZE(lpPE) = 336. PUT-LONG(lpPE, 1) = GET-SIZE(lpPE). /* Cycle thru process-records */ RUN Process32First(hSnapShot, lpPE, OUTPUT ReturnValue). DO WHILE ReturnValue NE 0: IF GET-STRING(lpPE, 37) = "Acrobat.exe" OR GET-STRING(lpPE, 37) = "Acrord32.exe" THEN DO: list = list + "~n". /* show process identifier (pid): */ pAdobePID = STRING(GET-LONG(lpPE, 9)) + " ". /* show path and filename of executable: */ list = list + GET-STRING(lpPE, 37). END. RUN Process32Next(hSnapShot, lpPE, OUTPUT ReturnValue). END. /* Close SnapShot-list */ RUN CloseHandle(hSnapShot, OUTPUT ReturnValue). END PROCEDURE. PROCEDURE CreateToolhelp32Snapshot EXTERNAL "kernel32" : DEFINE INPUT PARAMETER dwFlags AS LONG. DEFINE INPUT PARAMETER th32ProcessId AS LONG. DEFINE RETURN PARAMETER hSnapShot AS LONG. END PROCEDURE. PROCEDURE Process32First EXTERNAL "kernel32" : DEFINE INPUT PARAMETER hSnapShot AS LONG. DEFINE INPUT PARAMETER lpProcessEntry32 AS MEMPTR. DEFINE RETURN PARAMETER ReturnValue AS LONG. END PROCEDURE. PROCEDURE Process32Next EXTERNAL "kernel32" : DEFINE INPUT PARAMETER hSnapShot AS LONG. DEFINE INPUT PARAMETER lpProcessEntry32 AS MEMPTR. 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. /* =============== TEST ================ */ /* lpID is an array of PID's (Process Identifiers) */ SET-SIZE(lpId) = 1000. /* assume room for 250 pid's */ IF WINGetVersion() <> '98' THEN DO: /* 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) */ IF GetProcessName(PID) = 'Acrobat.exe' OR GetProcessName(PID) = 'Acrord32.exe' THEN ASSIGN viPID = INTEGER(PID). END. SET-SIZE(lpId) = 0. END. ELSE DO: RUN ListProcesses (OUTPUT viPID). END. IF viPID <> 0 THEN DO: RUN OpenProcess ({&PROCESS_TERMINATE}, 0, viPID, OUTPUT ProcessHandle). IF ProcessHandle NE 0 THEN DO: RUN TerminateProcess (ProcessHandle, 0, OUTPUT ReturnValue). RUN CloseHandle(ProcessHandle, OUTPUT ReturnValue). END. END.