mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
retrieve parent process id while obtaining processes list
(cherry picked from commit 70e08724586cc553aadfd250231688e0a3566d7c) IJ-MR-94381 GitOrigin-RevId: 684864540480750d36cf51837300174cb1e927aa
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6858e7d6f5
commit
00bf3987ff
Binary file not shown.
1
native/WinProcessListHelper/.gitignore
vendored
1
native/WinProcessListHelper/.gitignore
vendored
@@ -4,3 +4,4 @@
|
||||
Debug
|
||||
Release
|
||||
ipch
|
||||
.idea
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(""));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user