0

Part of my code deals with terminating a process with a user input using Window's command prompt. Here's a snippet from my project.

import subprocess

def kill_process():
    # Displays running processes similar to linux 'top' command.
    subprocess.call(['tasklist'])

    cmd = input('\nEnter process name or process ID to kill process: ')
    try:
        # Kills process via user input.
        subprocess.call(['taskkill', '/pid', cmd])
    except:
        print('Invalid process name or ID.\n')
        kill_process()

If the user enters an invalid process name or ID I get this error:

ERROR: The process "user_input" not found.

I believe this error isn't handled by python, but rather by Windows. Therefore, I can't catch the exception and handle it accordingly. When this error is raised it forces my code to exit, which is an issue because I need the code to continue, even threw user error.

I can parse threw the data and get process names / IDs using subprocess.check_output() with something like this;

cmd = input('\nEnter process name or process ID to kill process: ')

if cmd in subprocess.check_output(['tasklist'], encoding='UTF-8'):
    subprocess.call(['taskkill', '/pid', cmd])

but, if possible, I rather avoid this method. I might run into similar errors when dealing with CMD later down the line and parsing through this type of data can become tedious.

Eryk Sun
  • 33,190
  • 5
  • 92
  • 111
Legended
  • 119
  • 1
  • 6
  • Python isn't part of Windows yet you've tagged it with **two** Windows' tags. Your program CANNOT run on any standard Windows' computer. Think **What do you want from a Windows' person, you want a python person**? But having tagged it with professional tags what is this amateur hour stuff. Programmers program and don't use users commands. Do it properly https://www.activexperts.com/admin/scripts/wmi/python/0413/ – Noodles May 04 '19 at 19:57
  • How to do it WINDOWS VBS https://stackoverflow.com/questions/36120146/can-anyone-help-me-close-this-program-in-vbscript and VBNET list Windows https://pastebin.com/BfvdFkBq list attributes https://pastebin.com/v2TbfKAS list apps in a console https://pastebin.com/n9H1MBML List Environment https://pastebin.com/rrEyVxFd – Noodles May 04 '19 at 20:03
  • If a Python question relates to Windows, then of course it should be tagged as such. This script can run on a standard Windows computer, assuming the OP packages it as a Windows executable via PyInstaller or Py2Exe, or distributes it with portable Python, or simply requires Python to be installed. – Eryk Sun May 04 '19 at 21:58
  • Also, implementing a program such as taskkill.exe is an extensive amount of work that maybe the OP isn't prepared to handle. It entails enumerating top-level windows and message-only windows across all window stations and desktops in the session and sending `WM_CLOSE` messages to windows owned by the target process(es) as filtered by PID, name, window title, loaded modules, hosted services, etc. This gives the process a chance to exit gracefully. Merely calling `TerminateProcess` is bad form. – Eryk Sun May 04 '19 at 21:58

1 Answers1

2

taskkill returns a non-zero error code if the kill failed, and subprocess.call returns that code. Just check for that instead of using exceptions:

import subprocess

def kill_process():
    cmd = input('\nEnter process name or process ID to kill process: ')

    return_code = subprocess.call(['taskkill', '/pid', cmd])
    print(result)

    # 128 == no such process
    if return_code == 128: 
        print('Invalid process name or ID.\n')
        kill_process()

Note, in Python 3, which you seem to be using, subprocess.run seems to be preferred. sunprocess.call is listed under "Older high-level APIs". Sience run returns a CompletedProcess, you'll need to change the code a bit:

. . .
    comp_proc = subprocess.call(['taskkill', '/pid', cmd])

    if comp_proc.returncode == 128: 
        . . .
Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • I looked a bit into `subprocess.run`. I just wanted to note that return codes are handled a bit differently compared to `subprocess.call`. `run` returns [subprocess.CompleteProcess](https://docs.python.org/3/library/subprocess.html#subprocess.CompletedProcess). If you want to get an exit code you must use `returncode`. For this instance, I would use `subprocess.run(['taskkill', '/pid', cmd]).returncode`. Also, thanks for the insight. I'll start using `run` from this point on. – Legended May 04 '19 at 17:02
  • @Legended If I remember, I'll add a blurb about that when I get home. – Carcigenicate May 04 '19 at 17:10