retrieve parent process id while obtaining processes list

(cherry picked from commit 70e08724586cc553aadfd250231688e0a3566d7c)

IJ-MR-94381

GitOrigin-RevId: 684864540480750d36cf51837300174cb1e927aa
This commit is contained in:
Arseny.Chernyaev
2022-08-17 20:28:05 +02:00
committed by intellij-monorepo-bot
parent 6858e7d6f5
commit 00bf3987ff
7 changed files with 154 additions and 105 deletions

Binary file not shown.

View File

@@ -4,3 +4,4 @@
Debug
Release
ipch
.idea

View File

@@ -19,13 +19,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>

View File

@@ -189,6 +189,10 @@ int main(int argc, char **argv)
hr = pclsObj->Get(L"ProcessId", 0, &vtId, nullptr, nullptr);
INT pid = SUCCEEDED(hr) ? vtId.intVal : 0;
wcout << "pid:" << pid << "\n";
VARIANT vtParentId = { 0 };
hr = pclsObj->Get(L"ParentProcessId", 0, &vtParentId, nullptr, nullptr);
INT parentPid = SUCCEEDED(hr) ? vtParentId.intVal : 0;
wcout << "parentPid:" << parentPid << "\n";
VARIANT vtName = { 0 };
hr = pclsObj->Get(L"Name", 0, &vtName, nullptr, nullptr);
if (SUCCEEDED(hr) && vtName.bstrVal != nullptr)

View File

@@ -23,75 +23,78 @@ public class ProcessListUtilTest extends TestCase {
public void testMac_Basic() {
List<ProcessInfo> infos = ProcessListUtil.parseMacOutput(
" PID STAT USER COMM\n\n" +
" 1 S user /dir/file\n" +
" 2 S user ./dir/dir/file\n" +
" 3 S user ./dir/dir/file\n",
" PID STAT USER COMMAND\n\n" +
" 1 S user /dir/file\n" +
" 2 S user ./dir/dir/file\n" +
" 3 S user ./dir/dir/file param param"
" PID PPID STAT USER COMM\n\n" +
" 1 0 S user /dir/file\n" +
" 2 1 S user ./dir/dir/file\n" +
" 3 2 S user ./dir/dir/file\n" +
"10000 3 S user ./dir/dir/file",
" PID PPID STAT USER COMMAND\n\n" +
" 1 0 S user /dir/file\n" +
" 2 1 S user ./dir/dir/file\n" +
" 3 2 S user ./dir/dir/file param param\n" +
"10000 3 S user ./dir/dir/file param2 param2"
);
assertOrderedEquals(infos,
new ProcessInfo(1, "/dir/file", "file", "", "/dir/file"),
new ProcessInfo(2, "./dir/dir/file", "file", "", "./dir/dir/file"),
new ProcessInfo(3, "./dir/dir/file param param", "file", "param param", "./dir/dir/file"));
new ProcessInfo(1, "/dir/file", "file", "", "/dir/file", 0),
new ProcessInfo(2, "./dir/dir/file", "file", "", "./dir/dir/file", 1),
new ProcessInfo(3, "./dir/dir/file param param", "file", "param param", "./dir/dir/file", 2),
new ProcessInfo(10000, "./dir/dir/file param2 param2", "file", "param2 param2", "./dir/dir/file", 3));
}
public void testMac_DoNotIncludeProcessedMissingOnTheSecondPSRun() {
List<ProcessInfo> infos = ProcessListUtil.parseMacOutput(
" PID STAT USER COMM\n\n" +
" 1 S user /dir/file\n" +
" 2 S user /dir/file\n",
" PID STAT USER COMMAND\n\n" +
" 1 S user /dir/file\n" +
" 5 S user /dir/file\n"
" PID PPID STAT USER COMM\n\n" +
" 1 0 S user /dir/file\n" +
" 2 1 S user /dir/file\n",
" PID PPID STAT USER COMMAND\n\n" +
" 1 0 S user /dir/file\n" +
" 5 1 S user /dir/file\n"
);
assertOrderedEquals(infos, new ProcessInfo(1, "/dir/file", "file", "", "/dir/file"));
assertOrderedEquals(infos, new ProcessInfo(1, "/dir/file", "file", "", "/dir/file", 0));
}
public void testMac_DoNotIncludeProcessedChangedOnTheSecondPSRun() {
List<ProcessInfo> infos = ProcessListUtil.parseMacOutput(
" PID STAT USER COMM\n\n" +
" 1 S user /dir/file\n" +
" 2 S user /dir/file\n" +
" 3 S user /dir/file\n" +
" 4 S user /dir/file\n",
" PID STAT USER COMMAND\n\n" +
" 1 S user /dir/file param\n" +
" 2 S user /dir/ffff\n" +
" 3 S user /dir/file1\n" +
" 4 S user /dir/file/1\n"
" PID PPID STAT USER COMM\n\n" +
" 1 0 S user /dir/file\n" +
" 2 1 S user /dir/file\n" +
" 3 2 S user /dir/file\n" +
" 4 3 S user /dir/file\n",
" PID PPID STAT USER COMMAND\n\n" +
" 1 0 S user /dir/file param\n" +
" 2 1 S user /dir/ffff\n" +
" 3 2 S user /dir/file1\n" +
" 4 3 S user /dir/file/1\n"
);
assertOrderedEquals(infos, new ProcessInfo(1, "/dir/file param", "file", "param", "/dir/file"));
assertOrderedEquals(infos, new ProcessInfo(1, "/dir/file param", "file", "param", "/dir/file", 0));
}
public void testMac_DoNotIncludeZombies() {
List<ProcessInfo> infos = ProcessListUtil.parseMacOutput(
" PID STAT USER COMM\n\n" +
" 1 S user /dir/file\n" +
" 2 Z user /dir/file\n" +
" 3 SZ user /dir/file\n",
" PID STAT USER COMMAND\n\n" +
" 1 S user /dir/file\n" +
" 2 Z user /dir/file\n" +
" 3 SZ user /dir/file\n"
" PID PPID STAT USER COMM\n\n" +
" 1 0 S user /dir/file\n" +
" 2 1 Z user /dir/file\n" +
" 3 1 SZ user /dir/file\n",
" PID PPID STAT USER COMM\n\n" +
" 1 0 S user /dir/file\n" +
" 2 1 Z user /dir/file\n" +
" 3 1 SZ user /dir/file\n"
);
assertOrderedEquals(infos, new ProcessInfo(1, "/dir/file", "file", "", "/dir/file"));
assertOrderedEquals(infos, new ProcessInfo(1, "/dir/file", "file", "", "/dir/file", 0));
}
public void testMac_VariousFormsPidStatUser() {
List<ProcessInfo> infos = ProcessListUtil.parseMacOutput(
" PID STAT USER COMMAND\n\n" +
" 1 S user /dir/file\n" +
" 101 Ss user_name /dir/file\n",
" PID STAT USER COMM\n\n" +
" 1 S user /dir/file\n" +
" 101 Ss user_name /dir/file\n"
" PID PPID STAT USER COMMAND\n\n" +
" 1 0 S user /dir/file\n" +
" 101 1 Ss user_name /dir/file\n",
" PID PPID STAT USER COMM\n\n" +
" 1 0 S user /dir/file\n" +
" 101 1 Ss user_name /dir/file\n"
);
assertOrderedEquals(infos,
new ProcessInfo(1, "/dir/file", "file", "", "/dir/file"),
new ProcessInfo(101, "/dir/file", "file", "", "/dir/file"));
new ProcessInfo(1, "/dir/file", "file", "", "/dir/file", 0),
new ProcessInfo(101, "/dir/file", "file", "", "/dir/file", 1));
}
public void testMac_WrongFormat() {
@@ -119,46 +122,46 @@ public class ProcessListUtilTest extends TestCase {
));
assertEmpty(ProcessListUtil.parseMacOutput(
" PID STAT USER COMM\n\n" +
" 1 S user /dir/file\n",
" PID S USER COMMAND\n\n" +
" PID PPID STAT USER COMM\n\n" +
" 1 0 S user /dir/file\n",
" PID PPID S USER COMMAND\n\n" +
" \n"
));
assertEmpty(ProcessListUtil.parseMacOutput(
" PID S USER COMMAND\n\n" +
" PID PPID S USER COMMAND\n\n" +
" \n",
" PID STAT USER COMMAND\n\n" +
" 1 S user /dir/file\n"
" PID PPID STAT USER COMMAND\n\n" +
" 1 0 S user /dir/file\n"
));
}
public void testWindows_WMIC() {
List<ProcessInfo> infos = ProcessListUtil.parseWMICOutput(
"Caption CommandLine ExecutablePath ProcessId \n" +
"smss.exe 304 \n" +
"sihost.exe sihost.exe 3052 \n" +
"taskhostw.exe taskhostw.exe {222A245B-E637-4AE9-A93F-A59CA119A75E} 3068 \n" +
"explorer.exe C:\\WINDOWS\\Explorer.EXE C:\\WINDOWS\\Explorer.EXE 3164 \n" +
"TPAutoConnect.exe TPAutoConnect.exe -q -i vmware -a COM1 -F 30 3336 \n" +
"conhost.exe \\??\\C:\\WINDOWS\\system32\\conhost.exe 0x4 \\??\\C:\\WINDOWS\\system32\\conhost.exe 3348 \n");
"Caption CommandLine ExecutablePath ParentProcessId ProcessId \n" +
"smss.exe 0 304 \n" +
"sihost.exe sihost.exe 304 3052 \n" +
"taskhostw.exe taskhostw.exe {222A245B-E637-4AE9-A93F-A59CA119A75E} 0 3068 \n" +
"explorer.exe C:\\WINDOWS\\Explorer.EXE C:\\WINDOWS\\Explorer.EXE 3068 3164 \n" +
"TPAutoConnect.exe TPAutoConnect.exe -q -i vmware -a COM1 -F 30 3164 3336 \n" +
"conhost.exe \\??\\C:\\WINDOWS\\system32\\conhost.exe 0x4 \\??\\C:\\WINDOWS\\system32\\conhost.exe 0 3348 \n");
assertOrderedEquals(infos,
new ProcessInfo(304, "smss.exe", "smss.exe", ""),
new ProcessInfo(3052, "sihost.exe", "sihost.exe", ""),
new ProcessInfo(3068, "taskhostw.exe {222A245B-E637-4AE9-A93F-A59CA119A75E}", "taskhostw.exe", "{222A245B-E637-4AE9-A93F-A59CA119A75E}"),
new ProcessInfo(3164, "C:\\WINDOWS\\Explorer.EXE", "explorer.exe", "", "C:\\WINDOWS\\Explorer.EXE"),
new ProcessInfo(3336, "TPAutoConnect.exe -q -i vmware -a COM1 -F 30", "TPAutoConnect.exe", "-q -i vmware -a COM1 -F 30"),
new ProcessInfo(3348, "\\??\\C:\\WINDOWS\\system32\\conhost.exe 0x4", "conhost.exe", "0x4", "\\??\\C:\\WINDOWS\\system32\\conhost.exe"));
new ProcessInfo(304, "smss.exe", "smss.exe", "", null, 0),
new ProcessInfo(3052, "sihost.exe", "sihost.exe", "", null, 304),
new ProcessInfo(3068, "taskhostw.exe {222A245B-E637-4AE9-A93F-A59CA119A75E}", "taskhostw.exe", "{222A245B-E637-4AE9-A93F-A59CA119A75E}", null, 0),
new ProcessInfo(3164, "C:\\WINDOWS\\Explorer.EXE", "explorer.exe", "", "C:\\WINDOWS\\Explorer.EXE", 3068),
new ProcessInfo(3336, "TPAutoConnect.exe -q -i vmware -a COM1 -F 30", "TPAutoConnect.exe", "-q -i vmware -a COM1 -F 30", null, 3164),
new ProcessInfo(3348, "\\??\\C:\\WINDOWS\\system32\\conhost.exe 0x4", "conhost.exe", "0x4", "\\??\\C:\\WINDOWS\\system32\\conhost.exe", 0));
}
public void testOnWindows_WMIC_DoNotIncludeSystemIdleProcess() {
List<ProcessInfo> infos = ProcessListUtil.parseWMICOutput(
"Caption CommandLine ExecutablePath ProcessId \n" +
"System Idle Process 0 \n" +
"System 4 \n" +
"smss.exe 304 \n");
"Caption CommandLine ExecutablePath ParentProcessId ProcessId \n" +
"System Idle Process -1 0 \n" +
"System 0 4 \n" +
"smss.exe 0 304 \n");
assertOrderedEquals(infos,
new ProcessInfo(4, "System", "System", ""),
new ProcessInfo(304, "smss.exe", "smss.exe", ""));
new ProcessInfo(4, "System", "System", "", null, 0),
new ProcessInfo(304, "smss.exe", "smss.exe", "", null, 0));
}
public void testWindows_WMIC_WrongFormat() {
@@ -167,7 +170,7 @@ public class ProcessListUtilTest extends TestCase {
assertNull(ProcessListUtil.parseWMICOutput(
"wrong format"));
assertEmpty(ProcessListUtil.parseWMICOutput(
"Caption CommandLine ExecutablePath ProcessId \n"));
"Caption CommandLine ExecutablePath ParentProcessId ProcessId \n"));
assertNull(ProcessListUtil.parseWMICOutput(
"smss.exe 304 \n"));
@@ -178,7 +181,7 @@ public class ProcessListUtilTest extends TestCase {
"Caption CommandLine ExecutablePath XXX \n" +
"smss.exe 304 \n"));
assertEmpty(ProcessListUtil.parseWMICOutput(
"Caption CommandLine ExecutablePath ProcessId \n" +
"Caption CommandLine ExecutablePath ParentProcessId ProcessId \n" +
" \n"));
}
@@ -209,30 +212,34 @@ public class ProcessListUtilTest extends TestCase {
public void testWinProcessListHelperOutputParsing() {
List<ProcessInfo> infos = ProcessListUtil.parseWinProcessListHelperOutput(
"pid:19608\n" +
"parentPid:0\n" +
"name:SourceTree.exe\n" +
"cmd:\"C:\\\\Users\\\\grahams\\\\AppData\\\\Local\\\\SourceTree\\\\app-3.1.3\\\\SourceTree.exe\"\n" +
"pid:12300\n" +
"parentPid:0\n" +
"name:conhost.exe\n" +
"cmd:\\\\??\\\\C:\\\\Windows\\\\system32\\\\conhost.exe 0x4\n" +
"pid:26284\n" +
"parentPid:0\n" +
"name:Unity Hub.exe\n" +
"cmd:\"C:\\\\Program Files\\\\Unity Hub\\\\Unity Hub.exe\" --no-sandbox --lang=en-US --node-integration=true /prefetch:1\n" +
"pid:25064\n" +
"parentPid:12300\n" +
"name:cmd.exe\n" +
"cmd:\"C:\\\\WINDOWS\\\\system32\\\\cmd.exe\" /c \"pause\\necho 123\"\n"
);
assertOrderedEquals(
infos,
new ProcessInfo(19608, "\"C:\\Users\\grahams\\AppData\\Local\\SourceTree\\app-3.1.3\\SourceTree.exe\"", "SourceTree.exe", ""),
new ProcessInfo(12300, "\\??\\C:\\Windows\\system32\\conhost.exe 0x4", "conhost.exe", "0x4"),
new ProcessInfo(19608, "\"C:\\Users\\grahams\\AppData\\Local\\SourceTree\\app-3.1.3\\SourceTree.exe\"", "SourceTree.exe", "", null, 0),
new ProcessInfo(12300, "\\??\\C:\\Windows\\system32\\conhost.exe 0x4", "conhost.exe", "0x4", null, 0),
new ProcessInfo(26284,
"\"C:\\Program Files\\Unity Hub\\Unity Hub.exe\" --no-sandbox --lang=en-US --node-integration=true /prefetch:1",
"Unity Hub.exe",
"--no-sandbox --lang=en-US --node-integration=true /prefetch:1"),
"--no-sandbox --lang=en-US --node-integration=true /prefetch:1", null, 0),
new ProcessInfo(25064,
"\"C:\\WINDOWS\\system32\\cmd.exe\" /c \"pause\necho 123\"",
"cmd.exe",
"/c \"pause\necho 123\"")
"/c \"pause\necho 123\"", null, 12300)
);
assertNull(ProcessListUtil.parseWinProcessListHelperOutput(""));

View File

@@ -14,6 +14,7 @@ public class ProcessInfo {
public static final ProcessInfo[] EMPTY_ARRAY = new ProcessInfo[0];
private final int myPid;
private final int myParentPid;
@NotNull private final String myCommandLine;
@NotNull private final Optional<String> myExecutablePath;
@NotNull private final String myExecutableName;
@@ -23,11 +24,7 @@ public class ProcessInfo {
@NotNull String commandLine,
@NotNull String executableName,
@NotNull String args) {
myPid = pid;
myCommandLine = commandLine;
myExecutablePath = Optional.empty();
myExecutableName = executableName;
myArgs = args;
this(pid, commandLine, executableName, args, null, -1);
}
public ProcessInfo(int pid,
@@ -35,17 +32,31 @@ public class ProcessInfo {
@NotNull String executableName,
@NotNull String args,
@Nullable String executablePath) {
this(pid, commandLine, executableName, args, executablePath, -1);
}
public ProcessInfo(int pid,
@NotNull String commandLine,
@NotNull String executableName,
@NotNull String args,
@Nullable String executablePath,
int parentPid) {
myPid = pid;
myCommandLine = commandLine;
myExecutableName = executableName;
myExecutablePath = StringUtil.isNotEmpty(executablePath) ? Optional.of(executablePath) : Optional.empty();
myArgs = args;
myParentPid = parentPid;
}
public int getPid() {
return myPid;
}
public int getParentPid() {
return myParentPid;
}
@NotNull
@NlsSafe
public String getCommandLine() {
@@ -101,6 +112,7 @@ public class ProcessInfo {
if (!myArgs.equals(info.myArgs)) return false;
if (!myCommandLine.equals(info.myCommandLine)) return false;
if (!myExecutablePath.equals(info.myExecutablePath)) return false;
if (myParentPid != info.myParentPid) return false;
return true;
}
@@ -111,6 +123,7 @@ public class ProcessInfo {
result = 31 * result + myExecutableName.hashCode();
result = 31 * result + myArgs.hashCode();
result = 31 * result + myCommandLine.hashCode();
result = 31 * result + myParentPid;
return result;
}
}

View File

@@ -37,8 +37,8 @@ import java.util.List;
public final class ProcessListUtil {
private static final Logger LOG = Logger.getInstance(ProcessListUtil.class);
private static final String WIN_PROCESS_LIST_HELPER_FILENAME = "WinProcessListHelper.exe";
public static final List<@NlsSafe String> COMM_LIST_COMMAND = List.of("/bin/ps", "-a", "-x", "-o", "pid,state,user,comm");
public static final List<@NlsSafe String> COMMAND_LIST_COMMAND = List.of("/bin/ps", "-a", "-x", "-o", "pid,state,user,command");
public static final List<@NlsSafe String> COMM_LIST_COMMAND = List.of("/bin/ps", "-a", "-x", "-o", "pid,ppid,state,user,comm");
public static final List<@NlsSafe String> COMMAND_LIST_COMMAND = List.of("/bin/ps", "-a", "-x", "-o", "pid,ppid,state,user,command");
public static ProcessInfo @NotNull [] getProcessList() {
List<ProcessInfo> result = doGetProcessList();
@@ -185,7 +185,7 @@ public final class ProcessListUtil {
String name = PathUtil.getFileName(command);
String args = each.commandLine.substring(command.length()).trim();
result.add(new ProcessInfo(each.pid, each.commandLine, name, args, command));
result.add(new ProcessInfo(each.pid, each.commandLine, name, args, command, each.parentPid));
}
return result;
}
@@ -217,7 +217,7 @@ public final class ProcessListUtil {
String args = each.commandLine.startsWith(command) ? each.commandLine.substring(command.length()).trim()
: each.commandLine;
result.add(new ProcessInfo(each.pid, each.commandLine, name, args, command));
result.add(new ProcessInfo(each.pid, each.commandLine, name, args, command, each.parentPid));
}
return result;
}
@@ -228,10 +228,17 @@ public final class ProcessListUtil {
if (lines.length == 0) return null;
@NlsSafe String header = lines[0];
int pidStart = header.indexOf("PID");
String pidString = "PID";
int pidStart = header.indexOf(pidString);
if (pidStart == -1) return null;
int statStart = header.indexOf("S", pidStart);
String parentPidString = "PPID";
int parentPidStart = header.indexOf(parentPidString, pidStart);
if (parentPidStart == -1) return null;
int parentPidSectionStart = pidStart + pidString.length();
int statStart = header.indexOf("S", parentPidStart);
if (statStart == -1) return null;
int userStart = header.indexOf("USER", statStart);
@@ -244,16 +251,18 @@ public final class ProcessListUtil {
String line = lines[i];
try {
int pid = StringUtil.parseInt(line.substring(0, statStart).trim(), -1);
int pid = StringUtil.parseInt(line.substring(0, parentPidSectionStart).trim(), -1);
if (pid == -1) continue;
int parentPid = StringUtil.parseInt(line.substring(parentPidSectionStart, statStart).trim(), -1);
@NlsSafe String state = line.substring(statStart, userStart).trim();
if (state.contains("Z")) continue; // zombie
String user = line.substring(userStart, commandStart).trim();
String commandLine = line.substring(commandStart).trim();
result.add(new MacProcessInfo(pid, commandLine, user, state));
result.add(new MacProcessInfo(pid, commandLine, user, state, parentPid));
}
catch (Exception e) {
LOG.error("Can't parse line '" + line + "'", e);
@@ -264,15 +273,17 @@ public final class ProcessListUtil {
private static class MacProcessInfo {
final int pid;
final int parentPid;
final String commandLine;
final String user;
final String state;
MacProcessInfo(int pid, String commandLine, String user, String state) {
MacProcessInfo(int pid, String commandLine, String user, String state, int parentPid) {
this.pid = pid;
this.commandLine = commandLine;
this.user = user;
this.state = state;
this.parentPid = parentPid;
}
}
@@ -342,14 +353,14 @@ public final class ProcessListUtil {
static @Nullable List<ProcessInfo> parseWinProcessListHelperOutput(@NotNull String output) {
String[] lines = StringUtil.splitByLines(output, false);
List<ProcessInfo> result = new ArrayList<>();
if (lines.length % 3 != 0) {
logErrorTestSafe("Broken output of " + WIN_PROCESS_LIST_HELPER_FILENAME + ": output line count is not a multiple of 3");
if (lines.length % 4 != 0) {
logErrorTestSafe("Broken output of " + WIN_PROCESS_LIST_HELPER_FILENAME + ": output line count is not a multiple of 4");
LOG.debug(output);
return null;
}
int processCount = lines.length / 3;
int processCount = lines.length / 4;
for (int i = 0; i < processCount; i++) {
int offset = i * 3;
int offset = i * 4;
String idString = removePrefix(lines[offset], "pid:");
int id = StringUtil.parseInt(idString, -1);
if (id == -1) {
@@ -359,17 +370,25 @@ public final class ProcessListUtil {
}
if (id == 0) continue;
String name = unescapeString(removePrefix(lines[offset + 1], "name:"));
String parentIdString = removePrefix(lines[offset + 1], "parentPid:");
int parentId = StringUtil.parseInt(parentIdString, -1);
if (parentId == -1) {
logErrorTestSafe("Broken output of " + WIN_PROCESS_LIST_HELPER_FILENAME + ": parent process ID is not a number: " + lines[offset + 1]);
LOG.debug(output);
return null;
}
String name = unescapeString(removePrefix(lines[offset + 2], "name:"));
if (name == null) {
logErrorTestSafe("Failed to read a process name: " + lines[offset + 1]);
logErrorTestSafe("Failed to read a process name: " + lines[offset + 2]);
LOG.debug(output);
return null;
}
if (name.isEmpty()) continue;
String commandLine = unescapeString(removePrefix(lines[offset + 2], "cmd:"));
String commandLine = unescapeString(removePrefix(lines[offset + 3], "cmd:"));
if (commandLine == null) {
logErrorTestSafe("Failed to read a process command line: " + lines[offset + 2]);
logErrorTestSafe("Failed to read a process command line: " + lines[offset + 3]);
LOG.debug(output);
return null;
}
@@ -381,7 +400,7 @@ public final class ProcessListUtil {
else {
args = extractCommandLineArgs(commandLine, name);
}
result.add(new ProcessInfo(id, commandLine, name, args));
result.add(new ProcessInfo(id, commandLine, name, args, null, parentId));
}
return result;
}
@@ -409,7 +428,7 @@ public final class ProcessListUtil {
}
static @Nullable List<ProcessInfo> getProcessListUsingWindowsWMIC() {
return parseCommandOutput(Arrays.asList("wmic.exe", "path", "win32_process", "get", "Caption,Processid,Commandline,ExecutablePath"),
return parseCommandOutput(Arrays.asList("wmic.exe", "path", "win32_process", "get", "Caption,Processid,ParentProcessId,Commandline,ExecutablePath"),
ProcessListUtil::parseWMICOutput);
}
@@ -425,6 +444,9 @@ public final class ProcessListUtil {
int pidStart = header.indexOf("ProcessId");
if (pidStart == -1) return null;
int parentPidStart = header.indexOf("ParentProcessId");
if (parentPidStart == -1) return null;
int executablePathStart = header.indexOf("ExecutablePath");
if (executablePathStart == -1) return null;
@@ -435,7 +457,9 @@ public final class ProcessListUtil {
int pid = StringUtil.parseInt(line.substring(pidStart).trim(), -1);
if (pid == -1 || pid == 0) continue;
String executablePath = line.substring(executablePathStart, pidStart).trim();
int parentPid = StringUtil.parseInt(line.substring(parentPidStart, pidStart).trim(), -1);
String executablePath = line.substring(executablePathStart, parentPidStart).trim();
String name = line.substring(0, commandLineStart).trim();
if (name.isEmpty()) continue;
@@ -450,7 +474,7 @@ public final class ProcessListUtil {
args = extractCommandLineArgs(commandLine, name);
}
result.add(new ProcessInfo(pid, commandLine, name, args, executablePath));
result.add(new ProcessInfo(pid, commandLine, name, args, executablePath, parentPid));
}
return result;
}