Search code examples
javastringwindowssplittasklist

Parsing Windows tasklist output in Java


I am trying to build an array of processes running on my machine; to do so I have been trying to use the following two commands:

tasklist /fo csv /nh        # For a CSV output
tasklist /nh                # For a non-CSV output

The issue that I am having is that I can not properly parse the output.

First Scenario

I have a line like:

"wininit.exe","584","Services","0","5,248 K"

Which I have attempted to parse using "".split(","), however this fails when it comes to the process memory usage - the comma in the number field willl result in an extra field.

Second Scenario

Without the non-CSV output, I have a line like:

wininit.exe                    584 Services                   0      5,248 K

Which I am attempting to parse using "".split("\\s+") however this one now fails on a process like System Idle Process, or any other process with a space in the executible name.

How can I parse either of these output such that the same split index will always contain the correct data column?


Solution

  • To parse a string, always prefer the most strict formatting. In this case, CSV. In this way, you could process each line with a regular expression containing FIVE groups:

    private final Pattern pattern = Pattern
        .compile("\\\"([^\\\"]*)\\\",\\\"([^\\\"]*)\\\",\\\"([^\\\"]*)\\\",\\\"([^\\\"]*)\\\",\\\"([^\\\"]*)\\\"");
    
    private void parseLine(String line) {
    
        Matcher matcher = pattern.matcher(line);
    
        if (!matcher.find()) {
            throw new IllegalArgumentException("invalid format");
        }
    
        String name = matcher.group(1);
        int pid = Integer.parseInt(matcher.group(2));
        String sessionName = matcher.group(3);
        String sessionId = matcher.group(4);
        String memUsage = matcher.group(5);
    
        System.out.println(name + ":" + pid + ":" + memUsage);
    }