ok, a little bit tricky. the main thread of batch execution enters wait state after spawning notepad.exe. therefore, you can poll its state.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Test_ExecuteFromBatch
{
class Program
{
static void Main(string[] args)
{
try
{
int bid;
using (Process p = Process.Start("npad.bat"))
{
bid = p.Id;
while (p.Threads[0].ThreadState != System.Diagnostics.ThreadState.Wait)
{
Thread.Sleep(500);
Console.WriteLine(p.Threads[0].ThreadState);
p.Refresh();
}
};
var l = Process.GetProcessesByName("notepad").Select(i1 =>
new
{
ProcessName = i1.ProcessName,
Id = i1.Id,
StartTime = i1.StartTime
}).OrderByDescending(i1 => i1.StartTime);
int id = -1;
foreach (var item in l)
{
Console.WriteLine("{0} {1} {2}", item.ProcessName, item.Id, item.StartTime);
if (id < 0 && bid == GetOwnerPid(item.Id))
id = item.Id;
}
if (id > 0)
{
Console.WriteLine("{0}/{1}", bid, id);
Console.WriteLine(Process.GetProcessById(id).MainWindowTitle);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadKey();
}
static int GetOwnerPid(int pid)
{
int oid = -1;
string q = string.Format("Select * from Win32_Process Where ProcessID = {0}", pid);
using (ManagementObjectSearcher s = new ManagementObjectSearcher(q))
{
var o = s.Get().Cast<ManagementObject>().FirstOrDefault();
if (o != null)
{
oid = Convert.ToInt32(o.GetPropertyValue("ParentProcessId"));
}
}
return oid > 0 ? oid : -1;
}
}
}