Search code examples
javadetectionobs

How to find whether a process is running on Windows/Linux


I want my program to be able to detect whether OBS-Studio is currently running, and if it is, perform certain functionality in my program. The problem is I can't seem to find a solution that will work on both platforms. I've found things that use taskList, wmic.exe and others on windows, and I've found things using top, ps aux and others on linux, however these are very platform specific, and not easily ported. Is there a universal use case, and if so, what might it be?

I'm aware of ProcessHandle in Java9+, however my program runs Java8, with no current hope of upgrading, so that's not possible.


Solution

  • I ended up creating a method that would return a Map<Integer, String> for all processes by running os-specific commands:

    public Map<Integer, String> getProcesses() {
        final Map<Integer, String> processes = Maps.newHashMap();
        final boolean windows = System.getProperty("os.name").contains("Windows");
        try {
            final Process process = Runtime.getRuntime().exec(windows ? "tasklist /fo csv /nh" : "ps -e");
            try (final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                reader.lines().skip(1).forEach(x -> { // the first line is usually just a line to explain the format
                    if (windows) {
                        // "name","id","type","priority","memory?"
                        final String[] split = x.replace("\"", "").split(",");
                        processes.put(Integer.valueOf(split[1]), split[0]);
                    }
                    else {
                        // id tty time command
                        final String[] split = Arrays.stream(x.trim().split(" ")).map(String::trim)
                                .filter(s -> !s.isEmpty()).toArray(String[]::new); // yikes
                        processes.put(Integer.valueOf(split[0]), split[split.length - 1]);
                    }
                });
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    
        return processes;
    }
    

    This hasn't been tested on Windows, but it should work. It also hasn't been tested on literally anything else other than Linux, but I hope this serves as a helpful method for others to work off of.