3

How do I measure child process launch time in c#? I am currently using the following code to measure executable launch time and would like to add child process execution launch time, for example CMD running notepad or new tab in Chrome.

Here is my existing code for measuring "normal" process launch time:

  public static long LaunchProcess(String processFullPath)
        {
            Process process;
            var watch = System.Diagnostics.Stopwatch.StartNew();

            try
            {
                process = Process.Start(processFullPath);
                process.WaitForInputIdle();
                watch.Stop();
                etc....

Any help or direction will be highly appreciated!

klashar
  • 2,519
  • 2
  • 28
  • 38
Itamar Levy
  • 73
  • 1
  • 12

1 Answers1

1

So the trick is first to detect all child processes:

var mos = new ManagementObjectSearcher($"Select * From Win32_Process Where ParentProcessID={process.Id}");

Then, we can collect them in loop and start a new Task to measure the execution time. At the end loop through Task list and print the elapsed time.

public Tuple<int, TimeSpan> MonitorProcess(Process process)
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    process.WaitForExit();
    stopwatch.Stop();
    return Tuple.Create(process.Id, stopwatch.Elapsed);
}

public void LaunchProcess(String processFullPath)
{
    try
    {
        var tasks = new List<Task<Tuple<int,TimeSpan>>>();
        Process process = Process.Start(processFullPath);
        if (process == null) return;

        // Add my current (parent) process
        tasks.Add(Task.Factory.StartNew(()=>this.MonitorProcess(process)));

        var childProcesses = new List<Process>();
        while (!process.HasExited)
        {
            // Find new child-processes
            var mos = new ManagementObjectSearcher($"Select * From Win32_Process Where ParentProcessID={process.Id}");
            List<Process> newChildren = mos.Get().Cast<ManagementObject>().Select(mo => new { PID = Convert.ToInt32(mo["ProcessID"]) })
                .Where(p => !childProcesses.Exists(cp => cp.Id == p.PID)).Select(p => Process.GetProcessById(p.PID)).ToList();

            // measure their execution time in different task
            tasks.AddRange(newChildren.Select(newChild => Task.Factory.StartNew(() => this.MonitorProcess(newChild))));
            childProcesses.AddRange(newChildren);
        }

        // Print the results
        StringBuilder sb = new StringBuilder();
        foreach (Task<Tuple<int, TimeSpan>> task in tasks) {
            sb.AppendLine($"[{task.Result.Item1}] - {task.Result.Item2}");
        }

        this.output.WriteLine(sb.ToString());
    }
    catch (Exception ex)
    {

    }
}
Ofir Winegarten
  • 9,215
  • 2
  • 21
  • 27
  • You my friend are a genius! THANK you very much!! – Itamar Levy Feb 07 '17 at 16:05
  • Glad i could help @ItamarLevy. if this or any answer has solved your question please consider [accepting it](http://meta.stackexchange.com/q/5234/179419) by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this. – Ofir Winegarten Feb 07 '17 at 16:46