7

I'm currently writing a winforms application that is sensitive to programs being run in the background. At the moment I have a thread checking every second if the process I'm interested in has started/is still running, but I'm sure this would be much easier if I could just use an event to tell me when the user has opened/closed the application. Note that I am not starting the process manually within the program; the user has total control over that. Looking through the process documentation I don't see anything. Is there any way to hook into this?

ssb
  • 1,352
  • 3
  • 18
  • 40
  • You might find the answer here useful too: http://stackoverflow.com/questions/1916141/can-i-get-notified-when-some-process-starts – Baldrick Feb 12 '14 at 14:46
  • possible duplicate of [.NET Process Monitor](http://stackoverflow.com/questions/1986249/net-process-monitor) – Hans Passant Feb 12 '14 at 17:01

2 Answers2

6

You can also use WMI Events to track this.

Here is an example:

static void Main(string[] args)
{
    var query = new EventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance isa \"Win32_Process\"");

    using (var eventWatcher = new ManagementEventWatcher(query))
    {
        eventWatcher.EventArrived += eventWatcher_EventArrived;
        eventWatcher.Start();
        Console.WriteLine("Started");
        Console.ReadLine();
        eventWatcher.EventArrived -= eventWatcher_EventArrived;
        eventWatcher.Stop();
    }
}

static void eventWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
    try
    {
        var instanceDescription = e.NewEvent.GetPropertyValue("TargetInstance") as ManagementBaseObject;
        if(instanceDescription!=null)
        {
            var executablePath = instanceDescription.GetPropertyValue("ExecutablePath");
            if(executablePath!=null)
            {
                Console.WriteLine("Application {0} started", executablePath.ToString());
            }
         }
    }
    catch (ManagementException) { }
}

There are a lot of process attributes that can be received. Like Priority, Description, Command Line arguments, etc. You can look in instanceDescription.Properties for details.

Nick
  • 798
  • 1
  • 7
  • 14
  • That's very handy, nice and clean. And it shouldn't slow down the starting of new processes the way my solution might (if the hook is too slow). – Luaan Feb 13 '14 at 08:09
3

Well, at the very least, it should be possible to create a hook on the CreateProcess WinAPI method. You could even use that to prevent the process from starting at all (by simply returning false if you don't want the process to start). Of course, you'll have to make a hook on every method that can start a new process, but there's not all that many.

As Purrformance suggested, http://easyhook.codeplex.com/ is a great lib to easily create hooks from .NET.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • 2
    I was going to answer something similar, but since you did it, here's a +1. Also, it migth be worth mentioning [EasyHook](http://easyhook.codeplex.com/) – user703016 Feb 12 '14 at 14:43