Python 2.6 on Windows: how to terminate subprocess.Popen with "shell=True" argument? Python 2.6 on Windows: how to terminate subprocess.Popen with "shell=True" argument? windows windows

Python 2.6 on Windows: how to terminate subprocess.Popen with "shell=True" argument?


Why are you using shell=True?

Just don't do it. You don't need it, it invokes the shell and that is useless.

I don't accept it has to be True, because it doesn't. Using shell=True only brings you problems and no benefit. Just avoid it at all costs. Unless you're running some shell internal command, you don't need it, ever.


When using shell=True and calling terminate on the process, you are actually killing the shell, not the notepad process. The shell would be whatever is specified in the COMSPEC environment variable.

The only way I can think of killing this notepad process would be to use Win32process.EnumProcesses() to search for the process, then kill it using win32api.TerminateProcess. You will however not be able to distinguish the notepad process from other processes with the same name.


Based on the tip given in Thomas Watnedal's answer, where he points out that just the shell is actually being killed in the example, I have arranged the following function which solves the problem for my scenario, based on the example given in Mark Hammond's PyWin32 library:

procname is the name of the process as seen in Task Manager without the extension, e.g. FFMPEG.EXE would be killProcName("FFMPEG"). Note that the function is reasonably slow as it performs enumeration of all current running processes so the result is not instant.

import win32apiimport win32pdhutilimport win32condef killProcName(procname):    """Kill a running process by name.  Kills first process with the given name."""    try:        win32pdhutil.GetPerformanceAttributes("Process", "ID Process", procname)    except:        pass    pids = win32pdhutil.FindPerformanceAttributesByName(procname)    # If _my_ pid in there, remove it!    try:        pids.remove(win32api.GetCurrentProcessId())    except ValueError:        pass    handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, pids[0])    win32api.TerminateProcess(handle, 0)    win32api.CloseHandle(handle)