001package org.nuxeo.launcher.process; 002 003import static java.nio.charset.StandardCharsets.UTF_8; 004 005import java.io.IOException; 006import java.util.List; 007import java.util.regex.Matcher; 008import java.util.regex.Pattern; 009 010import org.apache.commons.io.IOUtils; 011 012/** 013 * {@link ProcessManager} implementation for Windows. 014 * <p> 015 * Requires wmic.exe and taskkill.exe, that should be available at least on Windows XP, Windows Vista, and Windows 7 016 * (except Home versions). 017 */ 018public class WindowsProcessManager implements ProcessManager { 019 020 protected static final boolean PID_ENABLED = true; 021 022 private static final Pattern PROCESS_GET_LINE = Pattern.compile("^(.*?)\\s+(\\d+)\\s*$"); 023 024 @Override 025 public String findPid(String regex) throws IOException { 026 Pattern commandPattern = Pattern.compile(regex); 027 for (String line : execute("wmic", "process", "get", "CommandLine,ProcessId")) { 028 Matcher lineMatcher = PROCESS_GET_LINE.matcher(line); 029 if (lineMatcher.matches()) { 030 String commandLine = lineMatcher.group(1); 031 String pid = lineMatcher.group(2); 032 Matcher commandMatcher = commandPattern.matcher(commandLine); 033 if (commandMatcher.find()) { 034 return pid; 035 } 036 } 037 } 038 return null; 039 } 040 041 @Override 042 public void kill(Process process, String pid) throws IOException { 043 execute("taskkill", "/t", "/f", "/pid", pid); 044 } 045 046 public boolean isUsable() { 047 try { 048 execute("wmic", "quit"); 049 execute("taskkill", "/?"); 050 return true; 051 } catch (IOException ioException) { 052 return false; 053 } 054 } 055 056 private List<String> execute(String... command) throws IOException { 057 Process process = new ProcessBuilder(command).start(); 058 process.getOutputStream().close(); // don't wait for stdin 059 List<String> lines = IOUtils.readLines(process.getInputStream(), UTF_8); 060 try { 061 process.waitFor(); 062 } catch (InterruptedException e) { 063 Thread.currentThread().interrupt(); 064 throw new RuntimeException(e); 065 } 066 return lines; 067 } 068 069 @Override 070 public boolean canFindPid() { 071 return PID_ENABLED; 072 } 073 074}