I've used the exact same code in my c# desktop application as it is given in here : https://github.com/gmamaladze/globalmousekeyhook
It works and fires the mousedown and keypress events as long as the application is in focus. If i'm on another application, let'say on visual studio (while mousekey logger is running), it doesn't fire the events.
Is it correct behavior? If so, any help to achieve this would be appreciated.
As suggested by #Hans Passant, application must be run in elevated mode if we have to track activity in other elevated applications. Running the ClickOnce application in Elevated mode was not so easy, i used this trick to achieve it. http://antscode.blogspot.com.au/2011/02/running-clickonce-application-as.html
Related
I'm writing a program that monitors state. It launches main window (LoginForm) to ask for user credentials, then hides the form. After that LoginForm inits NotifyIcon and all the remaining work is being done with LoginForm hidden. I've implemented all the clean-up work in FormClosing event of LoginForm. During normal exit process everything works perfectly.
The problem is that the program sits in tray all the time and I tend to forget to exit it before shutting down windows - program doesn't save the state on shutdown event.
I've read through many forums and docs, and from what I've read events FormClosing/FormClosed + SessionEnding/SessionEnded must fire anyway. But it looks like they just don't fire. Can't even cancel shutdown in SessionEnding (with stupid e.Cancel=true) - program disappears without reaching the place.
I've made myself a small debugging library to write out debug information into a file with instant flashing of cache. I've added debug messages to all the events. When I try to log off user in Windows (same as shutting down) for a test - I see no events being triggered usually, just the program vanishes. No exceptions I could catch, no events, etc. When exitting program manually or through "taskkill /IM " - I see all the expected debug printout. What's even more interesting - sometimes the program does reach closing events and does proper clean-up job during Windows shutdown.
Wasted a few days on this already. Overriden WndProc as suggested in MS article - program doesn't reach WndProc as well (to ensure it comes first before closing the form). Tried instead of FormClosing event to override OnClosing of LoginForm - no luck. Added UnhandledException handler, Microsoft.Win32.SessionEnding, Microsoft.Win32.SessionEnded, Form.FormClosing, Form.FormClosed event handlers - no luck.
I suspect this is either a problem of hidden forms or that some kind of exception is happening during shutdown only (resources disposed?). How can I find why that's happening? Is there some simple way to simulate Windows shutdown for single application to make debugging in VS possible? I've tried RMTool - for some reason it fails to simulate shutdown and program just ignores it.
Update: Program uses System.Timers.Timer to regularly poll server for any changes.
I've done some research into this, basically, after Windows XP they altered the way that shutdowns were handled.
You cannot block or capture the shutdown event reliably using the form_closing events etc.
You must use a new API to do so. There is a complete example here: http://bartdesmet.net/blogs/bart/archive/2006/10/25/Windows-Vista-2D00-ShutdownBlockReasonCreate-in-C_2300_.aspx
You should be able to call the function to block shutting down (display a message such as 'saving changes...') and then save and exit your application in the background. Once your program quits, it should allow windows to continue shutting down.
I think windows is simply configured to automatically shutdown all applications regardless and hence the application has no chance to catch SessionEnding events and so on : have a look at http://www.addictivetips.com/windows-tips/disable-automatic-termination-of-applications-during-shutdown-in-windows-7/ or check your configuration at Computer Configurations > Administrative Templates > System > Shutdown Options.
Hi I'm trying to make a simple program that read keys from keyboard even if my application is running in the background.
Situation
I want make a timer to help me in a game. I already have the program with the timer, the problem is I can not start the timer without switching of the game window to my app window. So I configured the game keyboard to release the keys F11, F12. Now in game this keys do nothing.
Problem
I built a windows forms containing a listener for keydown event and a conditional for F11. But when I trigger another window (eg the game window) my application no longer hears the keyboard, cuz it's in the background.
Question
How can I build a app that hears the keyboard, even if it's not active window?
You need to install a global, low-level keyboard hook using the SetWindowHookEx API call. Using the WH_KEYBOARD_LL hook will set your application up to intercept keyboard events at all times, even when your application is not active.
This post on MSDN shows an example of how to achieve something close to what you want from C#.
I have a C# .NET 2.0 application running on client kiosk machine (Windows XP) that occasionally puts up a window for user input. The other kiosk software seems to be interfering with it somehow because while it is running our window will not receive Mouse or Keyboard events despite it being the top window. When the other software is not running all works as expected. Does anyone have any insight as to what might be going on here?
Thanks
If in doubt - use Spy++ provided with Visual Studio to see what messages your window receives from the system.
If the other application blocks all input, it's not conforming to the Win32 API. That's why the low level hooks timeout was introduced in Vista and newer Win OS. Meaning a process would be kicked out of the low level hook chain, if it held onto a hook too long before calling CallNextHookEx() and not receive any low level hook messages anymore.
On Windows XP, there is no such limitation. A process can take as much time as they want to process a hooking message. The other program is either buggy, or evil. If it's essential that your application has input, then just close the other one programmatically or contact the author of it and explain the situation.
Take a look here
http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C
Using global keyboard hook should do just fine and some sources are included as well. Also, some user seem to solve similar problem by using ManagedSpyLib:
https://stackoverflow.com/a/8829286/1284902
After some digging, it is possible that the other windows forms program is utilizing a low level keyboard hook similar to one found here http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx. After following a link in that article, I came across a summary of that code snippet
For a concrete example of this, consider the (buggy) code in Figure 4. Using a low-level keyboard windows hook, the code intercepts all WM_KEYDOWN messages sent to any window and prints out the corresponding key.
Source: http://msdn.microsoft.com/en-us/magazine/cc163606.aspx
I'm working a small WPF based program for launching applications through system wide hotkeys implemented using hooking. I'm implementing it in C# and Visual Studio 2010.
When I detect the specific keypress I use Process.Start(...) to run the application. This works fine while Visual Studio is active, placing the new application in the foreground with input focus, as I would expect. If my launcher is in the background (behind another active program), it still detects the key and starts the application correctly, in front of everything else.
The problem is, that when I run the launcher without Visual Studio active, and my launcher application isn't front, neither will applications it starts. They appear in front of the launcher but behind the active application.
I can see that other software, like AutoHotkey, is able to do hotkey launching with this behavior, but I fail to see what I'm doing wrong.
Update: Just figured out a solution to this issue that works in my development environment. I first register a global hotkey through the Windows API RegisterHotKey using the launcher main window handle. The key could be any, but should be one that normally doesn't exist physically, F24 in my case. Then, whenever I detect a keypress through the hooks that should launch an app, I first call keybd_event to 'fake' a keypress for the hotkey.
For WPF use:
keybd_event((byte)KeyInterop.VirtualKeyFromKey(Key.F24),0,KEYEVENTF_KEYUP,0);
For WinForms use:
keybd_event((byte)Keys.F24,0,KEYEVENTF_KEYUP,0);
This will bring enough focus to the launcher, so that Process.Start(...) makes the executed program get in front. It does not bring the launcher window to front, nor does it make the launcher accept inputs.
If Activate() is called on the main window after the keybd_event(), this will bring the main window to front and allow for keyboard input, just as if the user had task switched.
I need to know which event fires within an WPF application if I cancel it by Windows Task Manager?
The idea is to terminate internal App. job accurately.
Thank you!
When you use the "Processes" tab there is no event, because your process is simply killed.
When you use the "Applications" tab, a normal WM_CLOSE message is sent to the top level of your application. See the last answer here on how to detect this in a WPF application.
The idea is to terminate internal App. job accurately.
You can't do this reliably. If the user is ending the application that way, something has either gone badly wrong or they simply don't care. There's nothing you can do, you're toast. Don't worry about cleaning up after yourself: the operating system will do that for you, no thank you required.
The best thing that you can do is handle the standard close events. Those will get triggered if the user requests to end your app in a polite way, either via the normal means or through Task Manager (Task Manager will try to ask nicely first if the user clicks "End Task" from the "Applications" tab). But since I assume you're already doing that, you've done all that you can.
Handling the event from Task Manager is not possible as the way it works for ungracefull shut downs of applications.
However, you can try to handle the Application class' SessionEnding event which is described in MSDN at below link:
http://msdn.microsoft.com/en-us/library/system.windows.application.sessionending.aspx