Killing Tasks on Windows with R
Nov 4, 2017
Curtis Alexander

On my Windows machine, I oftentimes want to kill a set of applications that are running. This is especially true when I don’t have full control of my machine and am unable to adjust the applications that launch on startup.

Below are two examples — both accomplish the same feat — that use R to call down to the OS and kill a list of tasks / applications. One example is more readable while the other is more terse. An alternative impetus for writing the short scripts below was to experiment with the processx package. A more portable way to accomplish would be to simply use PowerShell. But this was a fun exercise.

Taskkill — Readable, Annotated

# install (if applicable)
# install.packages(c("dplyr",
# "processx",
# "purrr",
# "readr"))
# libraries
suppressWarnings(suppressMessages(library("dplyr")))
suppressWarnings(suppressMessages(library("processx")))
suppressWarnings(suppressMessages(library("purrr")))
suppressWarnings(suppressMessages(library("readr")))
# list of applications to kill
kill_list <- c(
"calc.exe",
"notepad.exe"
)
# the below calls out to the operating system and runs
# the command "tasklist /fo csv" on the Windows command line
# its standard output -- what is printed on the screen --
# is captured and stored as a string within the list element named stdout
# stdout is then separated as a single character vector and piped into
# the read_csv function from readr
# the final result is a dataframe with the output from the tasklist command
# %>% and %$% are from either dplyr or purrr
task_list <- processx::run(commandline = "tasklist /fo csv") %$%
stdout %>%
readr::read_csv()
# filter the dataframe to just those tasks in the list above
# note the need for backquotes (``) for the column name as it contains
# and embedded space
tasks_to_kill <- task_list %>%
dplyr::filter(`Image Name` %in% kill_list)
# function for printing out the commands that will be run
print_task <- function(x) {
paste0("taskkill /f / pid ", x) %>% print()
}
# print out what is about to be performed
# extract out the PID column from the dataframe
# and pass each value of PID into the print_task function
# walk is used for iteratively applying a function that has
# side effects to each element in a list
tasks_to_kill %$%
PID %>%
purrr::walk(print_task)
# callback = simply echo the line back out
# using a callback is better than using the echo option within
# processx::run as it will not throw R errors but simply
# print out the standard error to the console
cb <- function(line, proc) {
cat(line, "\n")
}
# function to actually kill a task
kill_task <- function(x) {
processx::run(commandline = paste0("taskkill /f /pid ", x),
error_on_status = FALSE,
stdout_line_callback = cb,
stderr_line_callback = cb)
}
# iterate over all the tasks to kill, killing each one by one
tasks_to_kill %$%
PID %>%
purrr::walk(kill_task)
view raw taskkill.R hosted with ❤ by GitHub

Taskkill — Terse, Single Pipeline

# for checking and installing packages
# extracted from CRAmisc package
# https://github.com/curtisalexander/CRAmisc/blob/master/R/install.R
check_install <- function(pkgs, repos = NULL, ...) {
installed_packages <- installed.packages()[ ,1]
for (i in seq_along(pkgs)) {
pkg <- pkgs[[i]]
if (!pkg %in% installed_packages) {
cat(paste0("Need to install: ", pkg, "\n"))
if(is.null(repos)) install.packages(pkg, repos = "https://cran.rstudio.com")
else install.packages(pkg, repos = repos, ...)
} else cat(paste0(pkg, " already installed\n"))
}
invisible(pkgs)
}
req_pkgs <- list(
"dplyr",
"processx",
"purrr",
"readr"
)
check_install(req_pkgs)
# list of applications to kill
kill_list <- c(
"calc.exe",
"notepad.exe"
)
# callback
cb <- function(line, proc) {
cat(line, "\n")
}
# kill tasks using a single pipeline
taskkill <- function(klist) {
processx::run(commandline = "tasklist /fo csv") %$%
stdout %>%
readr::read_csv() %>%
dplyr::filter(`Image Name` %in% klist) %$%
PID %>%
purrr::walk(~ processx::run(commandline = paste0("taskkill /f /pid ", .),
error_on_status = FALSE,
stdout_line_callback = cb,
stderr_line_callback = cb))
}
taskkill(kill_list)