5

On Windows, I want to find a process by the name of 'exename.exe', and then kill it.

How can I do it by ctypes not any other 3rd-party module?

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Synapse
  • 1,574
  • 6
  • 18
  • 19
  • 2
    Call EnumProcesses and then TerminateProcess. – David Heffernan Aug 08 '11 at 09:44
  • Do you know ctypes at all? I'm just trying to work out what you know and what you don't know before I attempt to write code that does this. – David Heffernan Aug 08 '11 at 09:57
  • @David Heffernan -- Sorry, I just know something about ctypes, but I nearly do not know how to use ctypes to invoke advanced windows apis. I hope you can give me some guidance on how to use ctypes. Thank you – Synapse Aug 08 '11 at 10:15

2 Answers2

9

Try this:

import sys, os.path, ctypes, ctypes.wintypes

Psapi = ctypes.WinDLL('Psapi.dll')
EnumProcesses = Psapi.EnumProcesses
EnumProcesses.restype = ctypes.wintypes.BOOL
GetProcessImageFileName = Psapi.GetProcessImageFileNameA
GetProcessImageFileName.restype = ctypes.wintypes.DWORD

Kernel32 = ctypes.WinDLL('kernel32.dll')
OpenProcess = Kernel32.OpenProcess
OpenProcess.restype = ctypes.wintypes.HANDLE
TerminateProcess = Kernel32.TerminateProcess
TerminateProcess.restype = ctypes.wintypes.BOOL
CloseHandle = Kernel32.CloseHandle

MAX_PATH = 260
PROCESS_TERMINATE = 0x0001
PROCESS_QUERY_INFORMATION = 0x0400

count = 32
while True:
    ProcessIds = (ctypes.wintypes.DWORD*count)()
    cb = ctypes.sizeof(ProcessIds)
    BytesReturned = ctypes.wintypes.DWORD()
    if EnumProcesses(ctypes.byref(ProcessIds), cb, ctypes.byref(BytesReturned)):
        if BytesReturned.value<cb:
            break
        else:
            count *= 2
    else:
        sys.exit("Call to EnumProcesses failed")

for index in range(BytesReturned.value / ctypes.sizeof(ctypes.wintypes.DWORD)):
    ProcessId = ProcessIds[index]
    hProcess = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, False, ProcessId)
    if hProcess:
        ImageFileName = (ctypes.c_char*MAX_PATH)()
        if GetProcessImageFileName(hProcess, ImageFileName, MAX_PATH)>0:
            filename = os.path.basename(ImageFileName.value)
            if filename == 'notepad.exe':
                TerminateProcess(hProcess, 1)
        CloseHandle(hProcess)
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    by the way, can you recommend me some books or projects that I can dive in to learn more about ctypes and python, so that I improve my coding. I'm a freshman, just get started to learn python, and I found it fascinating. – Synapse Aug 08 '11 at 11:34
  • My favourite book to learn Python is [Learning Python](http://oreilly.com/catalog/9781565924642/). I don't think you'll find any printed material concerning ctypes since it is such a specialist topic. – David Heffernan Aug 08 '11 at 11:37
9

This may be cheating, but it works without even getting ctypes involved.

import subprocess
subprocess.call("taskkill /IM exename.exe")

taskkill is a Windows command; this is just invoking it through Python.

eric
  • 516
  • 3
  • 5
  • This is a super-elegant solution! People tend to forget that you can run arbitrary processes from within Python. +1 – Chinmay Kanchi Aug 08 '11 at 17:21
  • 2
    I'm certainly not above doing such a thing, but it is the opposite of elegant! The ctypes code is ugly but it directly invokes the OS routines immediately instead of building/parsing/running/tearing down another program to do it. – Gringo Suave Jan 17 '13 at 03:49
  • IT's far more elegant, because the ctypes code relies on stuff (internals) that is more likley to change than the other (command line app that windows tends to keep stable for integration into powershell) – Erik Aronesty Apr 25 '18 at 19:17
  • Just note: - taskkill without /f (force) will request a close not a kill and so may not actually terminate the process - taskkill also outputs to stdout, which you may not want - it reports a non-zero error code if the process is not running or if it simply fails to kill it - and in either case, the exit code is the same, but the error message may differ depending on the user's locale – Nick Desjardins May 09 '18 at 16:22