HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Windows CLI locks killer in Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
killercliwindowspythonlocks

Problem

Some coworkers and I sometimes want to delete folders, only to get the very informative: "Permission Denied" message. I had discovered Handle.exe and Process Explorer to help with this, but the method was still too manual and cumbersome.

Thus, I decided to write this Python CLI script to release locks on a given file. It runs Handle.exe under the hood and parses the output to prompt the user for confirmation to kill any given process (unless a quiet-like option flag is given).

We all work on Windows 7 using basically the same setup (IT takes care of setting up all the machines). The default Python is ActivateState's Python2.6.9. While some people use cmd.exe, a lot of guys use Bash or Cygwin, so I wanted to support all of these.

I am not sure if using logging solely for the purpose of adding a prefix to my output messages was a good idea, but it felt very redundant to add it to every print. Making a function that wraps print made the code look weird.

Also, I'm at a loss as to how to test this. I've added tests for abspath function (see repo), but I'm having trouble writing tests for the other functions.

```
"""Dammit let me delete this file!

Usage:
dammit [-y | -s]
dammit (-h)

Options:
-y Kill without permission.
-s Enable hotkey
-h Show this screen.

"""
from __future__ import print_function

from docopt import docopt
from functools import partial
import logging
import msvcrt
import os
import posixpath
import re
import subprocess
import sys
import time

log = logging.getLogger()
log.setLevel(logging.INFO)
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
PREFIX = 'dammit:'
formatter = logging.Formatter(PREFIX + ' %(message)s')
ch.setFormatter(formatter)
log.addHandler(ch)

CYGPATH = ['C:\\GnuNT\\bin\\cygpath.exe']
HANDLE = ["handle64.exe"]
# handle.exe provides way to close specified handle, which would be preferable,
# but this requires administrator rights :(
KILL = ["TASKKILL", "/f", "/pid"]
ACTIVATE = ["activate

Solution

String formatting

Generally, if you're using Python 2.6 or higher, you should be using the function str.format to format strings, rather than %. For example, this line in your code:

question = " Kill process %s with PID %s [y/n/s]? " % (process, pid)


Could become this:

question = " Kill process {process} with PID {pid} [y/n/s]? ".format(
    process=process,
    pid=pid
)


Another example would be turning this:

log.debug("Killed PID %s" % pid)


Into this:

log.debug("Killed PID {pid}".format(pid=pid))


Miscellaneous

On a small note, strings like this:

'C:\\GnuNT\\bin\\cygpath.exe'


Can be prefixed with r, like this so that you can do this, and get rid of the double-backslashes:

r'C:\GnuNT\bin\cygpath.exe'


Anything like this:

return None


Can simply be changed to this:

return


In the case of the kill function, the return at the end can be omitted completely.

Other than that, your code looks really nice and clean. Good job!

Code Snippets

question = " Kill process %s with PID %s [y/n/s]? " % (process, pid)
question = " Kill process {process} with PID {pid} [y/n/s]? ".format(
    process=process,
    pid=pid
)
log.debug("Killed PID %s" % pid)
log.debug("Killed PID {pid}".format(pid=pid))
'C:\\GnuNT\\bin\\cygpath.exe'

Context

StackExchange Code Review Q#96797, answer score: 3

Revisions (0)

No revisions yet.