views:

242

answers:

4

Hi.

Is there any way to get some Windows event when new application(s) gets added into memory/taskbar?
I can get running applications by iterating through Process.GetProcesses() (although, explorer processes will be excluded for some reason), but that means that I have to check for new processes every few seconds which isn't very good.
I was wondering if there's any interrupt that I can receive in C# application and then call the function to read the processes?

Any code samples would be great.
Thanks.

A: 

This might help. Since tnis involves hooking at the the NT level ( NtCreateFile() and NtOpenFile(), or NtCreateSection()) I'd suspect Managed C++ as the way to go.

Preet Sangha
Managed C++ isn't going to help you write a kernel driver, and hooking the NT native API is extremely difficult and dangerous.
bk1e
no one said is was easy. Having written kernel drivers my self - I should point out that the NT Api is user mode, its the Zw functions that are kernel mode.NT api site below Win32 but in UserMode.
Preet Sangha
Injecting a managed C++ DLL into every process on the system: also a bad idea. What happens to applications that want a different version of the CLR? Anyway, the example that you linked to was hooking in kernel mode, which is not portable to Vista 64-bit, and the way that it did it was vile.
bk1e
+1  A: 

WMI Events can alert you when a new process is created. Depending on the event you may have to poll. Using the Win32_ProcessStartTrace class you don't have to poll. New events are raised as events in your code. Below is an example (Add System.Management as a reference in your project)

public System.Management.ManagementEventWatcher mgmtWtch;
private delegate void ListBoxItemAdd(string Item);

public Form1()
{
    InitializeComponent();
    mgmtWtch = new System.Management.ManagementEventWatcher("Select * From Win32_ProcessStartTrace");
    mgmtWtch.EventArrived += new System.Management.EventArrivedEventHandler(mgmtWtch_EventArrived);
    mgmtWtch.Start();
}

    void AddItem(string Item)
    {
        if (lwProcesses.InvokeRequired)
            lwProcesses.Invoke(new ListBoxItemAdd(AddItem), Item);
        else
            lwProcesses.Items.Add(Item);
    }

    void mgmtWtch_EventArrived(object sender, System.Management.EventArrivedEventArgs e)
    {
        //MessageBox.Show((string)e.NewEvent["ProcessName"]);
        foreach (Process p in Process.GetProcesses("."))
        {
            string Title = p.MainWindowTitle;
            if (Title.Length > 0) AddItem(Title);
        }

    }

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    mgmtWtch.Stop();
}
Rob Haupt
This is it, thanks, although I get an error when closing the application -> Additional information: COM object that has been separated from its underlying RCW cannot be used.Last night (well in my time zone :)) I did found an answer with a little more code that don't throw an error.
lopkiju
I think you may need to dispose the WMI Object to avoid that error.
Rob Haupt
Yes, you're right.I have one problem though.I've created events for ProcessStartTrace and ProcessStopTrace and as I put a MsgBox, works, but when I am calling a function to populate the listview with processes, that doesn't work.
lopkiju
If I put a MsgBox instead, I get all running processes and function for populating work if it's on form load. I am puzzled about this.
lopkiju
The event, when raised, will only return the new event. Or in the case of processstoptrace, the ending process. To get a full list of the process, you should use Processes.GetProcesses()
Rob Haupt
I do use Processes.GetProcesses() like:Code snippet:foreach (Process p in Process.GetProcesses(".")) if (p.MainWindowTitle.Length > 0) lwProcesses.Items.Add(p.MainWindowTitle);But when I call that f-ion from the event, listView don't get populated for some reason.
lopkiju
The reason is that the event is fired in a different thread. Populating the Listbox would cross the thread. You instead need to use a delegate. I updated the code with the delegate and the AddItem function. I verified this code works as I believe you are expecting it to.
Rob Haupt
Thank you. That's what I wanted.I didn't assumed this was cross thread problem since there was no error it's just listview didn't get populated. When I worked with threads I would get a cross thread problem if I made such error and I would know. Thank you again.
lopkiju
A: 

Of course, (no need WMI), just use native create events)

+1  A: 

WMI is one approach. If not implement the idea after modifying code to c# via P/invoke as given in

http://www.codeproject.com/KB/threads/procmon.aspx

Best of luck.

lakshmanaraj