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:
KillProcessAPI('winrar.exe')
***********
Procedure KillProcessAPI(cAppName)
***********
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
Clear
cAppName = Upper(Alltrim(m.cAppName))
Declare Integer EnumProcesses In psapi.Dll ;
String @lpidProcess,;
Integer cb,;
Integer @cbNeeded
Declare Integer OpenProcess In win32api ;
Integer dwDesiredAccess,;
Integer bInheritHandle,;
Integer dwProcessId
Declare Integer GetModuleFileNameEx
In psapi;
INTEGER hProcess,;
INTEGER hModule,;
STRING ModuleName,;
INTEGER nSize
Declare Integer CloseHandle In win32api ;
Integer hObject
Declare Long GetExitCodeProcess
In kernel32 Long, Long @
Declare TerminateProcess
In WIN32API ;
INTEGER hProcess, ;
INTEGER fuExitCode
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), "\??\", ""))))
If !Empty(m.lcPN)
Insert Into junk Values (m.lcPN,m.lnPID)
ENDIF
IF
m.cAppName
= m.lcPN
* Terminate
target
lnExitCode = 0
GetExitCodeProcess(m.lnPH,
@lnExitCode)
TerminateProcess(m.lnPH,m.lnExitCode)
Endif
CloseHandle(lnPH)
Endif
Next
Endif
* Show the list of processes it was able to enumerate
Browse Normal
Clear DLLs
Endproc
**********
Function BUF2DWORD(cBuffer)
**********
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!
No comments:
Post a Comment