Я сделал хорошую реализацию на основе событий.
class Monitor
{
public event EventHandler ProgramStarted;
public event EventHandler ProgramClosed;
public Monitor(string process)
{
string pol = "2";
if (!process.EndsWith(".exe")) process += ".exe";
var queryString =
"SELECT *" +
" FROM __InstanceOperationEvent " +
"WITHIN " + pol +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + process + "'";
var s = @"\\.\root\CIMV2";
ManagementEventWatcher watcher = new ManagementEventWatcher(s, queryString);
watcher.EventArrived += new EventArrivedEventHandler(OnEventArrived);
watcher.Start();
}
private void OnEventArrived(object sender, EventArrivedEventArgs e)
{
if (e.NewEvent.ClassPath.ClassName.Contains("InstanceDeletionEvent"))
{
EventHandler handler = ProgramClosed;
handler?.Invoke(this, e);
}
else if (e.NewEvent.ClassPath.ClassName.Contains("InstanceCreationEvent"))
{
EventHandler handler = ProgramStarted;
handler?.Invoke(this, e);
}
}
}
Чтобы использовать его, вы просто создаете экземпляр класса и настраиваете события. Например:
static void Main(string[] args)
{
var mon = new Monitor("chrome");
mon.ProgramClosed += Mon_ProgramClosed;
mon.ProgramStarted += Mon_ProgramStarted;
Console.ReadKey(true);
}
private static void Mon_ProgramStarted(object sender, EventArgs e)
{
MessageBox.Show("Program started.");
}
private static void Mon_ProgramClosed(object sender, EventArgs e)
{
MessageBox.Show("Program closed.");
}
Не забудьте добавить ссылку на System.Drawing, если вы используете консольное приложение, и, для winforms, настройте модификаторы.