Windows – Subscribe to Vista Events in .NET (e.g. Window Opened)

eventswindows-vista

I am trying to build my own little toolbox for Vista.

One of the features is a "window placeing tool" which places the windows at saved position. Another tool I could imagine are extensions to firefox or thunderbird…

For these tools to work, I need them to be able to capture "Events" in Vista.
To give you a concrete example:

  • Explorer Opened New Window
  • User started Firefox
  • Mouse moved

For the mouse case, there are some examples for C#.
I also know about the directory watcher, nice little helper.

Want I now need is the "new window opened event"

Any idea how to monitor this, without iterating the current window list every 5 seconds (I already know how to get Windows using the DLLImports, and getting Processes using managed code. But I have no Event when the explorer process opens a new windows)

Thanks for your help,
Chris

Best Answer

What you're talking about doing is not simple by any stretch.

You're going to need to register a hook, and you're going to have to build a callback procedure that gets called within another process's execution context -- this is not going to be .NET code (probably C instead), and will have to be in a DLL. That callback procedure will get called every time a certain class of events happens. It will examine the events it receives and filter out the ones you're interested, then send your application the notifications you want (probably via PostMessage). You'll then tap in to your application's main message loop to intercept those messages, and from there you can fire a .NET Event, or whatever you want.

Writing hook callbacks is tricky stuff because the code gets run within another process, not your own, and the memory management and concurrency issues take a bit of forethought. For that same reason, it's not going to be done in C#. Ideally, though, this callback code will be very small and very fast, since it's going to get called so often.

Also note that while perfectly "legal" in Win32, these system hooks have an immense amount of power and are commonly used by malware to change the way your system works. For that reason, you may run afoul of antivirus software if you attempt to do this sort of thing on a customer's computer.

Also note that the far-reaching effects of system hooks also means that simple programming mistakes can take down your whole system, which you will probably discover for yourself at some point while debugging; so save everything before you hit "run".

Good luck!

EDIT

Did a bit more search to see if there's any way to write the hook proc in C#, and came up with this:

How to set a Windows hook in Visual C# .NET

This is almost what you're looking for, but not quite. Hook procedures can either be global (which means that they run on every application) or thread (only runs within your application). The document states that:

Global hooks are not supported in the .NET Framework

Except for the WH_KEYBOARD_LL low-level hook and the WH_MOUSE_LL low-level hook, you cannot implement global hooks in the Microsoft .NET Framework. To install a global hook, a hook must have a native DLL export to inject itself in another process that requires a valid, consistent function to call into. This behavior requires a DLL export. The .NET Framework does not support DLL exports. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically.

Which means, again, to monitor things that go on outside your application's view, you need to set a global hook, which can't be written in .NET.