I'm writing code that is part of an automation system. I wanted to add a keyboard hook to end the test prematurely, and I did this by using SetWindowHookEx.
My code looks pretty much like this: http://support.microsoft.com/kb/318804
Here's my SetWindowsHookEx call:
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
Now, when I run my automation, keypresses from within the automation system (from SendKeys) trigger the keyboard hook method, but when I hit the keyboard manually it isn't triggered.
I can share more code if that helps, but it's part of a much larger system. I'm pretty sure that either:
My SetWindowsHookEx isn't correct, or
Something in the automation system is bypassing my keyboard hook (I don't really know how to tell though).
I've written a test application that uses the sample code from microsoft.com to determine that my approach has merit (i.e., it works), but I'm having trouble integrating it with the automation system.
Any thoughts on how to determine where things are going wrong would be greatly appreciated.
Edit: There are no other instances of SetWindowsHookEx in the automation harness. I'm not too clear the nuances of global keyboard hooks w.r.t. threads and the desktop. If I add a global keyboard hook, should it matter from where it was added?
George Mamaladze's article Processing Global Mouse and Keyboard Hooks in C# which works if the application is "in the background" on CodeProject has been around since 2004, been through multiple revisions, and he's still supporting it and updating it : as I understand it, he started his project because he could not implement global hooks in .NET, that worked when the app was running in the background, but later discovered you could hook certain "lower level" events : formerly Q318804 : now MSDN article revised (?) that says you can hook WH_KEYBOARD_LL.
Perhaps, since George's code has been field-tested by so many C# programmers, over so many years, and extensively revised against bugs or problems : there's some possible value in his code for you ? In his article, in the Version 1 "FAQ" he shows code that will make the hook application specific, rather than global.
The MSDN article cited above mentions ... in the context of the allowed hooking of low level events, as you are doing :
"Low-level hook procedures are called
on the thread that installed the hook.
Low-level hooks do not require that
the hook procedure be implemented in a
DLL."
Hypothesis : could threading be related to what you are observing ?
I'm assuming you've already been through and considered all the details on : MSDN : LowLevelKeyboardProc Function
Responding to your comment -
If you just need to test whether a key is down in order to exit your test, you could just poll on GetAsyncKeyState(), this will tell you if a particular key is down regardless of who currently has keyboard focus.
You user would have to hold a key or set of keys down long enough for your polling to notice, which means either they hold it down for a few seconds, or you have to poll more frequently than a second.
But that would be a lot less intrusive than a global keyboard hook.
Global hooks supposedly serialize parts of the kernel that normally would be async from each other, so they also harm system performance.
Related
It's incredibly easy to write Key-loggers in many languages. It makes me a little nervous because these small, unknown viruses won't get detected by most(read: all) antivirus'.
I'm curious how to detect if some process grabbing these keys. I want to know what process is reading my input at any given point. Kind of a Key-logger-logger.
several answers available on these questions
List of installed windows hooks
Detecting Keyboard Hooks
what are the methods to find hooked functions and apis
I would like to hook all the functions calls of all running processes. I can hook certain function("ws2_32.dll!recv") of all processes using deviare by:
CreateSpyMgr(out mgr);
hook = mgr.CreateHook("ws2_32.dll!recv");
hook.Attach(mgr.get_Processes(0));
mgr.set_ReportProcessCreation(DeviareCommonLib.ReportMethod._create_process_hook_and_polling, 0);
hook.set_HookNewProcesses(0, 1);
hook.OnFunctionCalled += new DHookEvents_OnFunctionCalledEventHandler(hook_OnFunctionCalled);
hook.Hook();
How can I hook all function calls instead of just one? is it possible?
Or should I create hooks collection(of all functions which is way hard) using INktSpyMgr::CreateHooksCollection and add hooks to it, then call hook method and pass the INktHooksEnum object as the parameter. Is this the only way to do this?
My aim is to make a tool that counts all system calls for each running process. Feel free to give any suggestions.
First a word of advice: be very very careful about which APIs you hook. If anything you do within your hook method results in a call to one of the APIs you are hooking then you are creating an infinite recursion that could potentially wreck your computer. Bear that in mind. You'll probably want to filter out the API calls for your own process as well, otherwise you'll end up logging entries about the disk access caused by logging entries, and before you know it your memory is full and the hard drive is fully occupied with logging about logging.
There appears to be nothing in the Deviare API that allows you to create hooks on multiple methods - no wildcards or 'hook everything' calls - so you'll have to enumerate the APIs (see INktModule.ExportedFunctions for some ideas) and hook them. I'd suggest that you use a hook collection (see INktSpyMgr.CreateHookCollection and INktHooksEnum) so that you can setup all your hooks and then attach and detach them in one operation.
As for the logging aspect, give some thought to using a queue of some sort - ConcurrentQueue<T> by preference - to pass the actual logging operations off to another thread. That way you spend a minimum of time in the actual hook function as well as reducing the chances of your hooks causing recursion. You'll have to experiment with filtering in the logging thread vs the hook functions to find out which has the smaller performance impact on the system.
Always make sure you know how much data your program is dealing with and have a plan in place for dealing with the volume of data. You're going to have to do some serious profiling to find the pain points, then put in plenty of work on reducing the overheads so that your program doesn't mess up the system too badly.
Personally I'd start with a small subset of the APIs you ultimately want to monitor, write code that works as well as you can make it, then move up to the full set of APIs. Less chance that you'll kill your computer that way.
Ok, long story short I have a Windows service that handles Win32_VolumeChangeEvent and logs USB disk device arrivals to the Event Log and to a SQL database. An additional component to this is a hidden UI (WinForms) which loads in the user session at login - this pops up a message box reminding users of company policy about USB keys etc. AFAIK, this was the best way to go since services can no longer run in interactive mode.
Anywho... architecturally, v1 of this little thing ran with the UI component handling WndProc messages for device insertion, then passed the device identifier through IPC (named pipes) to the service which would handle WMI methods / EventLog writing (as not all users have local admin rights). This had the downside of the UI element being process killed and no longer detecting device insertions.
So, current version is that the service handles Win32_VolumeChangeEvents and gets the needed details from the device, then logs to EventLog and SQL. All is outstanding and works perfectly. Except now I'm wondering what the best way to trigger the UI into displaying the popup is.
I've researched around Google and here, looking for ideas about eventing over IPC, so I can just subscribe to an event from the UI component and fire it within the service, but I'm not finding much that jumps out as being helpful. I'm also constrained to .net2, so WCF is out of the picture (although I'm not afraid of p/invoke if you want to go that way).
So. How would you do it? Links, thoughts, ramblings, pseudocode, actual code... all is appreciated. I'm trying to stick to what I believe is best practice, although I also think programming is a bit of an art form and my best practice may be someone else's horror story.
So SO - what would you do? Let me know if I need to clarify :)
Back in the bad old days of Windows API programming, we'd sometimes use RegisterWindowMessage to register a unique message ID that (presumably) only our window knew how to handle. We could then trigger that window from another application by calling PostMessage with a window handle of HWND_BROADCAST, and the msg parameter being that unique message value. That works great if everything you want to share between the processes can fit into two DWORD values (wparam and lparam). Sharing more data can be done if you allocate global memory and pass a reference as one of the parameters.
That should still be possible with .NET. Certainly there's no trouble calling PostMessage. As for handling the message in the UI code, you have to override the Form's WndProc. See How do I send/receive windows messages between VB6 and c#? for an example.
You could do something with named events, although that would only notify the UI that some change had occurred. It wouldn't actually tell you what happened. I suppose, if there's only a small set of possible events, you could have multiple events, but that gets complicated pretty quickly.
You could go the named event route and use shared memory (memory mapped file) to share the state.
Or, you could set up sockets, named pipes, TcpListener/TcpClient, or even a UdpClient. All should work, with varying degrees of complexity and/or reliability.
The only idea that comes to my mind is to have a service check the state of the UI application periodically and restart it if it has been killed. There seems to be no standard module that would run within user's session and let the service send notifications to this module. There exist third-party solutions but they can be killed (not saying that they should be installed in order to be used).
Update: after re-reading the question I think that maybe your UI doesn't receive windows messages, so you need another mechanism. Why not create a Semaphore synchronization object in service and wait for it in UI process (in a separate thread)?
I would like to get notification of when any/all programs are being actively used.
To do this via windows hooks I'd use an unmanaged C++ dll that talks to C#. There is an article that explains this process here.
I was wondering though if there is any alternative to using system hooks though.
I haven't looked at all of the details of this library, but it might help you out.
Managed Windows API
C++ is not required to set a global windows hook, you just need to call the necessary winapis.
A global hook would be more efficient and more reliable than polling, assuming you are only interested in applications that have a window associated with the process. For example, a CMD prompt may not generate GWH events.
Ultimately the most reliable and efficient mechanism would be a system-wide injection, a good start would be the Detours library from Microsoft Research. Jefffrey Richter's classic "Advanced Windows Programming" book covered this in detail, offering 3 mechanisms for injection (including how to set up a system wide hook). Again, this doesn't require C++, and wouldn't necessarily tell you when an application was in use. Ultimately global window hooking is going to make the most sense.
List running processes:
http://codefreezer.com/codedetail.php?article=13
Determine which process is topmost:
http://www.pinvoke.net/default.aspx/user32/getwindowthreadprocessid.html
I'm trying to write what I hope is a simple application tracker. That is, whenever a new application starts, or a running application becomes current, I want to note the event and start timing it's time "on top".
I have code that lists all the current applications that are running, and some code that tells me the top window (always my test console app, naturally).
What I think I'm missing is the Windows event stream to monitor or something.
I'm using .NET (C# preferred).
Any hints, tips or cheats available?
Thanks - Jonathan
I think the best way to do this would be using windows "hooks" (i.e. SetWindowsHookEx). These allow you to hook in to windows core functionality, specifically there is one called WH_CALLWNDPROC which calls a user function any time any window in the system receives a message.
You could use this to globally listen for messages that bring a window to the foreground, and/or messages for user interaction (mouse, keyboard).
However, this is a raw Windows API function primarily meant for use in a C/C++ windows DLL. You can implement it in C#, but that is a can of worms you may not want to open. But opening it would probably be the best way of doing what you're asking.
I'm not sure if there's a way to hook a Windows event, but simply polling System.Diagnostics.Process.GetProcesses() at regular intervals (say, 100ms) and looking for new/removed processes (comparing by process ID) should do the job. Also, Process.StartTime will give you the time at which the process began.
Caveat: This method may be require a higher amount of processing compare an event-based method (none of which I am aware). Processes that start and end between each poll will not be observed, but this ought to be quite rare indeed for a reasonably high polling frequency (and perhaps you do not even care about these processes anyway). Saying this, these are minor detractions, and I would recommend you at least test this solution as it is fairly simple.
This is increasingly a SO problem, the down-voted answer is the correct one. SetWindowsHookEx() is indeed required to be able to catch the WM_ACTIVATE message that the activated window gets. But that requires a WH_CALLWNDPROC or WH_SHELL hook, hooks that cannot be implemented in C#. Catching those requires injecting a DLL in every process, a managed assembly cannot be injected into another process. The CLR cannot be initialized.
+1 for Noldorin to get him back to 0, that's all I can do. The OP needs to write his code in unmanaged C/C++, creating a DLL and use a standard IPC mechanism like pipes or sockets to notify the host app. Or poll, much easier.
I once wrote a small app that did this to keep track of my own work habits. What I did was call GetForegroundWindow() periodically (every 5 seconds or something) and noted the application that is running. You can get a lot of information from the window handle, not just the title but all the way down to the actual process that created it.
This is what I did using Java's JNA:
final HWND child = User32Ext.INSTANCE.GetForegroundWindow();
final int length = User32.INSTANCE.GetWindowTextLength(child) * 2;
final byte[] buffer = new byte[length];
User32.INSTANCE.GetWindowText(child, buffer, length);
title = new String(buffer, Charset.forName("UTF-16LE"));
where User32Ext is an extension I did because User32 (in JNA's distribution) doesn't have the interface for:
LRESULT callback(int nCode, WPARAM wParam, LPARAM lParam);
I'm periodically polling the active window, since I couldn't use the HCBT_SETFOCUS hook as mentioned in http://msdn.microsoft.com/en-us/library/ms997537.aspx, and I'll be very interested if someone comes up with the solution.