How to be notified a program execution and termination in c#? - c#

is there a way to be notified when a program is executed or terminated by a user in c#? I am talking about all the programs that a user can execute, not just a certain program. I would like to be notified whenever a user execute .exe files.
I can't even think of a keyword to google.
any suggestions would be appreciated!

The closest thing I know of would be to use Hooks.
You can use WH_SHELL Hooks to receive notification any time a new, non-owned, top level window is created or destroyed by the system. This isn't the same as a process, but it's pretty close in many cases, and potentially more useful in others (since it'd show a new word document window opening after one was already opened, even though they're using a shared process).
You might be able to combine that with EnumProcess to check to see if the process list has changed. This would work for tracking windows applications (but not services or console-based applications running in an existing console).

In Microsoft .NET Framework 3.5, you can get a list of Processes and register for the Process.Exited event. I suppose someone could implement a polling system in which they continually looked for new Processes, but that doesn't really notify you when something launches.
-- EDIT --
You might find this article useful. If you're willing to write a kernel mode driver, you can control every process start and finish.
Now, if you really want to get wild, you can hook into Microsoft Detours. Here is an interesting article about that.

Related

C# WPF app with MahApps failing to display in Windows 2008

So this is a weird one.
I created a WPF application using MahApps for the GUI. So far my testing indicates that the app works fine on several different machines. Of course this is not the case on the client's machine.
The client makes use of Terminal Services and Windows Server 2008R2. Several users can be logged into their own version of the server at anytime. The app starts up fine once or twice, but after a day or so, it no longer opens up.
The app doesn't show up in the Application tab of Task Manager, but its process can be seen to be running in Processes Tab of Task Manager.
To be honest, I'm completely stumped. I had a look at the event manager log and couldn't find anything indicative of a problem. (Of course I might have missed something). I saw another SO question suggesting to disable hardware acceleration, but I'm not if that would help.
Any and all ideas would be greatly appreciated.
EDIT:
I thought I might mention the only thing that helps is if we restart the client machine.
EDIT:
I think I have isolated the issue to integration with Twain (should probably have mentioned that as another possible factor). I think the Twain library (unmanaged code) somehow stalls without sending back an error. Disabling it has "fixed" the issue.
This somehow relates to Twain and multi-session setups. I'm almost sure of it.
First you can analyze the wait chain in Windows Resource Monitor to check if there are any resources the process is waiting for. (You can find more information about the wait chain here or here.)
If you don't find any viable suspects there, you can create a memory dump of the hanging process and analyze the call stacks. If you don't know how to create one, you can read about it here. If you want to use Windows Task Manager and your OS is 64-bit then please be aware that you need to use the same bitness of Task Manager as the application.
That is: If your application is 64-bit then you have to use C:\Windows\System32\taskmgr.exe and if it's 32-bit you have to use C:\Windows\SysWOW64\taskmgr.exe. If you forget this important step you'll just get an unusable dump full of gibberish.
After you got the memory dump you can either load it into WinDbg (using the same bitness as the application) or Visual Studio (best to use 2015 or later) and analyze the call stacks of all running threads.
You can download WinDbg here and read about the necessary WinDbg configuration here. For the list of all threads you need to use this SOS command.
If you need help in loading memory dumps into Visual Studio you can find more information here.
After you've looked at the call stacks you most definitely find the answer what is waiting on what resources and is thus preventing the shutdown or startup of the application. It can either be a classic deadlock or an external resource like writing/reading of a file or some other waiting without a timeout like accessing a database or an URL that can't be reached at the moment. And of course it can also be just an infinite loop - if it doesn't consume much CPU then perhaps with some kind of DoEvents in between.
And last but very not least: If you are really interested what can be analyzed if an application hangs you can read about an example analysis done by the absolutely awesome great Mark Russinovich here.

Certain applications stopping all attempts at getting keystrokes

So for work they have me writing a simple program for tracking employee efficiency within their workflow (things like using keyboard shortcuts, window locations, how often they need to look stuff up). Currently we want to track the 'F5' key (brings up next work item), 'Alt+Tab' (changes windows), 'Ctrl+V' (paste), but may be expanded as they find there are more shortcuts or things they want to track.
Note We are on windows 7, and using c# to write the tracking program.
In order to do this I wrote a low-level hooking library to capture the chosen keystrokes, send off the message down the hook chain and then add a note to a db that the key was used. The hooking library works great in All web browsers and most normal programs (except we don't actually care about browsers so we ignore everything done in them).
The issue is that the application that they use for managing their work (the program we actually care about tracking) some how stops our hooks from hooking and I do not know how. The application in question is TA2000 Desktop.
I know that with the way hooks work if an application fails to call callnexthook() within the LowLevelHooksTimeout period that the system kills the hook. So figuring maybe TA2000 was just taking to long or something I bumped up the timeout to 30 seconds (yes I know this is significantly more time than a hook should even need) but this had no effect.
The next thing I tried was implementing a tracking system based on the Raw Input API. And once again the tracking tracks on browsers, Microsoft office, notepad, and all the other programs I opened except it still is unable to track key press in TA2000. This really surprised me because according to MSDN
An application does not have to detect or open the input device.
An application gets the data directly from the device, and processes the data for its needs
An application can distinguish the source of the input even if it is from the same type of device. For example, two mouse devices.
So if I am getting the data directly from the device how is TA2000 preventing me from also getting the key press?
The last thing I could think of trying was using dll injection on TA2000 to inject a hook. However this method seems risky because It is something neither I nor any other developer here has any experience with and the application we want to track is operation critical so messing it up can not happen and injecting code into its memory space seems like a good way to mess things up.
If someone could explain how TA2000 could be stopping me from tracking keystrokes and how to beat it or point me in a good direction I would be very appreciative.
p.s. This felt questionable as an appropriate question for the SO format but it also feels specific enough to be a viable question. So sorry if this is not a good question but I am at my wits end with this.
This financial software package is secured to prevent snooping. Running the key logging software as Administrator appears to fix this specific problem. The security was identified initially using Sysinternals' Process Explorer, which is a great starting point for unexpected problems like this.

How to hook NTShutdownSystem in C# in order to differentiate between shutdown and reboot

unfortunatly, when you listen to WM_QUERYENDSESSION, you do not get the information if the user has requested a reboot or a shutdown. This is really bad design, but it's the way Windows is, so I was thinking of hooking the call to NTShutdownSystem, which gets a parameter telling the system to perform a reboot or to shutdown.
The question is: how can this actually be achieved in C#? I want to get some kind of hook that I can use to determine the parameters passed to NTShutdownSystem, and then save that information. After that, I want to call the "real" NTShutdownSystem the way it was intended by the user.
Do you have any sample code illustrating this?
The reason why WM_QUERYENDSESSION does not give a shutdown reason is that the user may just be logging out at that time, rather than shutting down the system.
This generally falls under the category of kernel level hooking and has generally not been considered a good thing as it can influence stability of the system. Most of them are written in C or C++, and generally have to go to a lot of effort to perform the hook across all the programs that are executing - e.g. hooking the routines at program load-time.
This is not a trivial, but there are some frameworks that have been written to help with trying to hook routines like this using managed code (e.g. C#)
The next question to ask is why do you care?
edit NTShutdownSystem is invoked very late in the shutdown process - at that point you probably have no UI and no way of doing anything. I would recommend intercepting ExitWindowsEx, InitiateShutdown, InitiateSystemShutdown and InitiateSystemShutdownEx - I don't know if some of them are called by the other, but you should probably only record the reason and then react to the reason in the WM_QUERYENDSESSION code of your standard app.

Is it possible to detect when a low-level keyboard hook has been automatically disconnected by Windows?

I am working on a program that uses keyboard hooks. However, when the PC that the program is running on is just slightly overloaded, it causes Windows to disconnect the hook from the program, causing it to no longer respond to keystrokes.
Is there a way to prevent this, or even better, propose a different way of solving the exact same problem, by using a different architecture, maybe involving a pipeline?
You can't "detect" this, and you absolutely shouldn't need to. What you're describing is a feature, specifically one introduced in Windows 7 to protect your system from rogue applications.
The applicable documentation describes it thusly (pay particular attention to the bolded section):
The hook procedure should process a message in less time than the data entry specified in the LowLevelHooksTimeout value in the following registry key:
HKEY_CURRENT_USER\Control Panel\Desktop
The value is in milliseconds. If the hook procedure times out, the system passes the message to the next hook. However, on Windows 7 and later, the hook is silently removed without being called. There is no way for the application to know whether the hook is removed.
The solution here is most certainly not to figure out a way to "detect" when the hook is uninstalled and reinstall it. You should have figured out that you're doing something wrong when the operating system uninstalled the hook the first time.
The actual solution is to redesign your application to return from the hook procedure more quickly. Ideally, you should return almost immediately. If you need to run some type of intensive calculation in response to the low level messages (and I can't really imagine why you would), then you should store the information you receive, return from the hook procedure, and do your processing at a later time (probably on a separate thread).
In fact, that's almost exactly what the documentation continues on to suggest:
Note: Debug hooks cannot track this type of low level keyboard hooks. If the application must use low level hooks, it should run the hooks on a dedicated thread that passes the work off to a worker thread and then immediately returns. In most cases where the application needs to use low level hooks, it should monitor raw input instead. This is because raw input can asynchronously monitor mouse and keyboard messages that are targeted for other threads more effectively than low level hooks can. For more information on raw input, see Raw Input.
I am not so sure that the keyboard hook is always to blame. We all seem to agree that under ideal or average conditions everything should be responsive. But during its lifetime from startup to shutdown a hook also has to survive some worst-case scenarios. In my company we wrote some keyboard hooks, and they are as lightweight and asynchronous as possible, yet they still occasionally appear to get disconnected.
As a user, every day I type several ten-thousand characters. I reboot once a month at best, and on occasions I am guilty of skipping a Windows Update. With options like suspend and hibernate, I don't think I am alone. As a developer, I have to make sure that the hook keeps running from beginning to end, regardless of what happens to the system.
Normally my system is very responsive. But there can be brief, exceptional moments where it is on its knees to the point that even Windows Aero gets switched off. Right now it is very snappy. But if I press the Show Desktop button, the mouse will freeze for at least a second during the time that my 65 or so open windows are all collapsed. What if I press a key during one of these moment?
If Windows can freeze the mouse for one second, if Windows can even switch off Aero during a brief moment of heavy load, why can't a keyboard hook be allowed to survive a similar exceptional time of overload? Instead, because of one exceptional moment, Windows pulls the plug, silently affecting the remaining computing experience until system shutdown. For 200 ms affecting just one keypress out of the thousands we press every day, for just that fraction of a second, I, the user, have to reboot the system because that's the only way I understand will bring back the keyboard macro or whatever utility I depend on for my productive work.
Even if it was guaranteed to prevent the above (which worst-case experience seems to suggest is not the case), I am not so sure that everything can easily be done in a separate thread. For example, let's say the user sets up a hotkey that is to start an application. Couldn't there be reasons for starting the application from the current context (foreground window, privileges, etc.)? And wouldn't it be reasonable for the user to actually expect and accept a delay, because he knows that, using the keyboard, he just started something that takes longer? I don't know if the example is technically sound, but I wanted to illustrate how sometimes things that otherwise may be unacceptable could be acceptable, as a result of a known event.
Keyboard hooks can be very useful for many things, from macros to error correction to launching things, and this behavior introduced in Windows 7 is putting the good and the bad, the acceptable and the unacceptable, the average and the exceptional, all in the same basket. This hurts both users, because quality keyboard hooks may get killed, and developers. Just imagine what a support nightmare it is when you have no official solution to your application working well under normal conditions, but being killed at random under some heavy load (or other inexplicable) circumstance.
To conclude this with a question, does anyone know what the status is under Windows 8, has anything changed?
Cody Gray's response is excellent, but FWIW, and purely for testing purposes, you may be able to detect a disconnected hook.
When your hook proc is invoked, store the current tick count in a variable accessible to the main thread. In the main thread, periodically call GetLastInputInfo. It will give you the tick count for the last input event in the system (not just in your process). If the value provided by GetLastInputInfo is significantly later (newer) than your last hook proc tick count, it's a good guess that hook has been disconnected.
I think there are some "bad-performance" code in your hook . that's the reason why makes slightly overload .
"it causes Windows to disconnect the hook from the program"
Does any error raise in your hook and you don't handle it ?
AFAIK, Windows wouldn't disconnect the hook if it works well by itself.
Try increasing priority of the process of your application.

Prevent C# app from process kill

How can I protect my C# app from someone killing its process via taskman or programmatically?
Here is my scenario:
App A is an MFC app developed by another team. It has an unpublished text-based remote interface that is enabled via a backdoor.
I'm developing app B, a C# WinForms app which interacts with A. B enables A's backdoor when it needs remote access closes it when finished (or on failure).
I'm exploring ways users could abuse B in order to gain access to A's hidden functionality, such as killing B's process after it has enabled A's remote interface. I'd like have one last chance for B to close A's backdoor when that happens.
B uses localhost to interact with A, so I'm not worried about the power-down scenario.
I'm looking for a solution that doesn't involve changing A.
I'm not expecting to be able to stop Dark Tangent (though that would be a bonus), but right now a script kiddie could have his way with this design :)
These apps run on Windows XP, but will also soon support Vista & 7.
Thanks in advance,
Jim
I'm willing shut the app down when they try but need to do some things first.
Having necessary steps at program shutdown leads to fragile programs that break easily. Even if you could prevent someone from killing your program via the task manager, you cannot stop them from turning off the computer, or even pulling the cable out of the wall. Whatever task that was so vitally important to complete will be lost. And what if there is a power cut? Again your task won't complete and your vital clean up code will not be run.
Instead you should make your program robust to failures at any point. Use transactions, and always save state to files atomically - make sure that you always have at least one valid copy of your data. Don't overwrite important files in a way that they become temporarily invalid.
Finally, you can add a dialog box to your program that when they try to close it, warns them that the program needs to shut down properly. If you make your shutdown fast users won't want to kill it and will let it terminate properly. If your shutdown takes ages then people will try to kill it. If you are nice to your users, they will be nice to you too.
If shutting down fast means that the user will lose some unfinished work then warn them about this and give them the opportunity to wait for the task to finish, but if they really want to quit your program then let them quit.
You can't - as long as the user has the right to call TerminateProcess on your program, you can't prevent End Process from killing you immediately in task manager. Raymond Chen posted on this some time ago: The arms race between programs and users
You really, really, really don't want to do this. It makes users very angry!! However, if it is supposed to be a service, run it as a service account and don't give admin rights to users.
Short answer: you can't and you shouldn't.
Long answer: You can try to start a second 'helper' process, that checks every x seconds if your app is still running. If it isn't, it restarts it.
If you want a process to run for a long time just don't trust users to keep it running, consider windows services. They are designed for this.
I think everybody has missed the point. If I read it correctly (after your edit) you wish to know when you are being "killed" so you can shut down gracefully?
The point of "killing" is that you "can't" stop it. There are of course workarounds like using a second app to revive a killed app, but that has nothing to do with simply being able to shut down gracefully.
The best approach is to either run as a service (so you can't be killed, just asked to shut down), or to restructure the way your app works so that it doesn't need to "tidy up" before it quits. When an app is quit, most resources it holds are automatically cleaned up, so it's only really your own data that you have to close cleanly. Approaches you could try are:
Frequently commit your state to disk so that you don't lose much (or anything) if you are unexpectedly quit. (Remember to flush all I/O streams to be sure they are committed to disk)
Save information to disk that allows you to detect an unexpected shutdown the next time your program runs, so it is able to detect and rectify whatever problems might have been caused by being killed.
Tell your users not to be idiots, and quit your application nicely. Poke them in the eye if they ignore you. Usually after no more than two times they listen :-)
In order to prevent your application from being terminated, you run your application as another user (i.e. as a service, or as another user account), and limit users to be Standard User.
This way no malicious users can kill your process, since only administrators can kill it, and that is a privilege that you, apparently, don't trust anyone with.
It has the advantage of following the intended design of the operating system.
#Jim
If App A can receive modification requests
Preferably, I would an architecture where all App B's are registered upon opening the backdoor and are required to ping App A with the registration at an interval so that App A can close it's own backdoor upon App B not informing it that it still needs access. This is still not perfectly secure but App A should not be structured with such an interface without some sort of self regulation for "secure" means of communication.
Or, you could suggest App A be modified to check for valid processes and if none are found while it's backdoor is open then it gets closed (this is spoofable since it goes by processed name).
Otherwise, it sounds like App B should shut the backdoor as often as possible when it does not need immediate access.
Requiring an App B to provide security of access to App A is a poor model indeed.
As far as i know you can't, and even if you could you really shouldn't. imagine how annoying it would be if you couldn't force kill an application.
If its important that your application keep running you could always create a windows service that "pings" the application to ensure it is running (you could use named pipes, sockets, pid files... whatever). if the service detects that the process has died then it can just restart it. this is probably your best bet.
When the application initiates for the first time could you not execute a 3rd ap/process that is running in the background and attempts to callback to App B every so ofter, so when that App B is closed.. App C can see that and executes a procedure to close App A's backdoor.
So that when App B closes successfully via the intended Close button it will disable App C from checking App B is still working fine...
Im not really the best with C# at the moment but looking at your problem thats probably one of the ways i would try to do it..
Also if App B checks App C aswell then if App C has gone down App B will close the backdoor if it can.
As the others say this may not be a good idea tho.

Categories