By passing a String[] array rather than a single String, you are telling the system to run a single .exe file whose name contains about 144 characters, the first thirteen of which are cmd /c for /f. Obviously there is no .exe file with that name.
One thing you can try is passing that single String to the exec(String) method instead of passing an array of Strings. This may or may not work, as Java will split your string into whitespace-delimited words, and then Windows will heuristically try to figure out what you want.
Another approach that may work is a String array containing 3 elements:
String[] command = { "cmd", "/c", "for /f \"tokens=5\" %a in ('netstat -noa -p tcp ^| find /i \"CLOSE_WAIT\" ^| find /i \""+ip+":443\" ') do if not \"%a\"==\"0\" echo taskkill /pid %a" };
The best thing to do, in my opinion, is not to rely on cmd.exe for parsing command line arguments. I suspect Java is at least as efficient at processing text:
Collection<String> pids = new ArrayList<>();
ProcessBuilder p = new ProcessBuilder("netstat.exe", "-noa", "-p", "tcp");
p.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE);
Process netstat = p.start();
try (BufferedReader output =
new BufferedReader(new InputStreamReader(netstat.getOutputStream()))) {
String line;
while ((line = output.readLine()) != null) {
if (line.toUpperCase().contains("CLOSE_WAIT") &&
line.contains(ip + ":443")) {
String[] tokens = line.split("\\s+");
String pid = tokens[4];
if (!pid.equals("0")) {
pids.add(pid);
}
}
}
}
if (netstat.waitFor() != 0) {
throw new IOException("netstat command failed");
}
p.inheritIO();
for (String pid : pids) {
Process taskkill = p.command("taskkill.exe", "/pid", pid).start();
taskkill.waitFor();
}
If you're using Java 8, you can also use Streams to write code that more closely resembles piped commands:
ProcessBuilder p = new ProcessBuilder("netstat.exe", "-noa", "-p", "tcp");
p.inheritIO().redirectOutput(ProcessBuilder.Redirect.PIPE);
Process netstat = p.start();
try (BufferedReader output =
new BufferedReader(new InputStreamReader(netstat.getOutputStream()))) {
final ProcessBuilder taskkill = new ProcessBuilder().inheritIO();
output.lines()
.filter(line -> line.toUpperCase().contains("CLOSE_WAIT") &&
line.contains(ip + ":443"))
.map(line -> line.split("\\s+")[4])
.filter(pid -> !pid.equals("0"))
.forEach(pid ->
taskkill.command("taskkill.exe", "/pid", pid).start());
}
if (netstat.waitFor() != 0) {
throw new IOException("netstat command failed");
}
cmdfirst and check whether that command is a valid command or not!