A question inside Foxite was raised yesterday requesting for a way to kill selected Windows processeses using API calls as what we normally use is the scripting way. And googling around, there are ways shown by several developers; but none, AFAIK, that terminates successfully a process on each run/attempt.
My first attempt yesterday combining information I gleamed across the web from several developers were not able to close the target process on every run. Digging further, one fault I see is my usage of GetModuleFileNameEx is failing to get a proper result thus skipping onto the next process among processes list.
With the belief that everything is possible given enough time and attention, when I arrived back in the office this morning, I renewed experimenting on the task; playing with different values and finally I settled with dwDesiredAccess value of 1041 here for the OpenProcess API call as this gets the proper handle necessary later on terminating my target process, though it skips some vital OS processes.
For whatever reason, said value of 1041 also gets more result than the PROCESS_ALL_ACCESS value which I expected to give more result. Maybe in the future I will play further with this, or maybe not anymore.
I included in this function a cursor showing the remaining processes it was able to acquire showing the Process Name and ID. This is optional as in reality we do not need this unless out of maybe a curiosity? Here are the codes:
Local lnLoop, lnBytesReturned, lnPID, lnPH, lcBuffer, lnSize
* This is just so we can see the processess in task manager
Create Cursor junk (pname c(40), pid i)
Index On pname Tag pname
cAppName = Upper(Alltrim(m.cAppName))
Declare Integer EnumProcesses In psapi.Dll ;
Declare Integer OpenProcess In win32api ;
Declare Integer GetModuleFileNameEx In psapi;
Declare Integer CloseHandle In win32api ;
Declare Long GetExitCodeProcess In kernel32 Long, Long @
Declare TerminateProcess In WIN32API ;
INTEGER hProcess, ;
lnSize = 4096 * 4
lnBytesReturned = 0
lcBuffer = Replicate(Chr(0), m.lnSize)
lnResult = EnumProcesses(@lcBuffer,m.lnSize,@lnBytesReturned)
If m.lnResult <> 0
For lnLoop = 1 To lnBytesReturned / 4
lnPID = BUF2DWORD(Substr (m.lcBuffer, 4 * (m.lnLoop - 1) + 1, 4))
lnPH = OpenProcess(1041, 0, m.lnPID)
If lnPH <> 0
lnResult = GetModuleFileNameEx(lnPH, 0,@lcBuffer, 255)
lcPN = Alltrim(Upper(Justfname(Strtran(Left(m.lcBuffer, m.lnResult), "\??\", ""))))
Insert Into junk Values (m.lcPN,m.lnPID)
IF m.cAppName = m.lcPN
* Terminate target
lnExitCode = 0
* Show the list of processes it was able to enumerate
Return Asc(Substr(m.cBuffer, 1.1)) +;
ASC(Substr(m.cBuffer, 2.1)) * 256 +;
ASC(Substr(m.cBuffer, 3.1 )) * 65536 +;
ASC(Substr(m.cBuffer, 4.1)) * 16777216
Hope this helps as well! Cheers!