Legended
Legended

Reputation: 129

Is there a way to handle Window's command line errors?

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.

Upvotes: 0

Views: 447

Answers (1)

Carcigenicate
Carcigenicate

Reputation: 45726

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: 
        . . .

Upvotes: 2

Related Questions