public static CommandContext GetAsync(Device device, Action <EntryCollection <int, ProcessEntry> > onFinished) { var processByPid = new Dictionary <int, ProcessEntry>(); var threadByTid = new Dictionary <int, ThreadEntry>(); ProcessEntry currentProcess = null; string state = "header"; // header -> process -> thread -> process -> ... var oldStyle = oldStyleByDevice.GetOrAdd(device, d => { bool result = false; // 新形式「」旧形式「bad pid '0'」 device.RunCommandOutputTextAsync("shell ps 0", (output, error) => result = output.StartsWith("bad")).Wait(); return(result); }); var command = oldStyle ? "shell ps -p -t" : "shell ps -eTwO PRI,NAME"; string[] columnNames = null; return(device.RunCommandAsync(command, output => { if (output == null) { onFinished?.Invoke(new EntryCollection <int, ProcessEntry>(processByPid)); return; } PsEntry psEntry = null; if (columnNames != null) { psEntry = new PsEntry(output, columnNames); } if (state == "thread" && currentProcess != null) { var tid = oldStyle ? psEntry.Pid : psEntry.Tid; var pid = oldStyle ? psEntry.Ppid : psEntry.Pid; var priority = psEntry.Priority; var name = oldStyle ? psEntry.ProcessName : psEntry.ThreadName; if (pid == currentProcess.Pid) { var thread = new ThreadEntry(tid, priority, name, currentProcess); threadByTid.Add(tid, thread); } else { state = "process"; } } if (state == "process") { threadByTid = new Dictionary <int, ThreadEntry>(); currentProcess = new ProcessEntry(psEntry); currentProcess.Threads = new EntryCollection <int, ThreadEntry>(threadByTid); processByPid.Add(currentProcess.Pid, currentProcess); state = "thread"; } if (state == "header") { if (oldStyle) { output = output.Replace("PC NAME", "PC S NAME"); } columnNames = output.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); state = "process"; } })); }
ProcessEntry(PsEntry psEntry) { this.psEntry = psEntry; }