How can I get the total time this application spent in the foreground, measured in milliseconds? When in the foreground, the user is actively interacting with the application. I need it for all windows installed applications every hour.
The closest solution that I found - https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.totalprocessortime?view=net-5.0
But this solution is per process and without consideration process state (background/foreground)
It sounds like you want to monitor end-user application use. For that I'd recommend a global hook, however, global hooks in .Net are either extremely limited or blocked. Here's a old project that uses a C++ DLL from .Net to create the actual hook: https://www.codeproject.com/articles/6362/global-system-hooks-in-net
I don't think there is a hook for when a Application / Window becomes active though. So what you might want to do is add a Mouse Hook, and then use something like http://pinvoke.net/default.aspx/user32/GetForegroundWindow.html to get the handle of the current Active Foreground Window.
Compare that handle to the last handle you retrieve. If different, record a start date/time, and then use other functions get more info about the Window in question (such as Title bar and exe name).
Then every time you detect a change, record a end date/time, calculate the difference between the start / end time, and put that into a Dictionary<Handle, Long> that tracks total ticks for each Handle.
One caveat is Alt+Tab. You might need a keyboard hook as well.
One alternative to maybe check out is this article I found:
https://www.c-sharpcorner.com/article/active-application-watcher-in-net-using-windows-forms/
Seems to also be doing what you want, but instead of it being a Mouse / Keyboard hook, it just has a Timer that fires every half second, and grabs the active foreground Window. The downside of that approach is accuracy (course even the hook isn't going to 100% precise).
If you go for the latter, I'd recommend swapping out the Timer control for something else. The System.Windows.Forms.Timer class is not precise - so it might fire every half second, but it might not - especially if the CPU Usage spikes cause of another app. Course other types of Timers are going to have issues with CPU Usage spikes, but Forms.Timer is probably the least precise of all the options available.
Related
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.
I have been given a windows service written by a previous intern at my current internship that monitors an archive and alerts specific people through emails and pop-ups should one of the recorded values go outside a certain range. It currently uses a timer to check the archive every 30 seconds, and I have been asked if I would be able to update it to allow a choice of time depending on what "tag" is being monitored. It uses an XML file to keep track of which tags are being monitored. Would creating multiple timers in the service be the most efficient way of going about this? I'm not really sure what approach to take.
The service is written in C# using .NET 3.5.
Depending on the granularity, you could use a single timer that is a common factor of the timing intervals they want. Say they want to put in the XML file that each archive is to be checked every so many minutes. You set up a timer that goes off once a minute, and you check how long it's been since you did each one and whether to do it or not.
If you're getting a chance to re-architect, I would move away from a service to a set of scheduled tasks. Write it so one task does one archive. Then write a controller program that sets up the scheduled tasks (and can stop them, change them etc.) The API for scheduled tasks on Windows 7 is nice and understandable, and unlike a service you can impose restrictions like "don't do it if the computer is on battery" or "only do it if the machine is idle" along with your preferences for what to do if a chance to run the task was missed. 7 or 8 scheduled tasks, each on their own schedule, using the same API of yours, passing in the archive path and the email address, is a lot neater than one service trying to juggle everything at once. Plus the machine will start up faster when you don't have yet another autostart service on it.
Efficient? Possibly not - especially if you have lots of tags, as each timer takes a tiny but finite amount of resources.
An alternative approach might be to have one timer that fires every second, and when that happens you check a list of outstanding requests.
This has the benefit of being easier to debug if things go wrong as there's only one active thread.
As in most code maintenance situations, however, it depends on your existing code, your ability, and how you feel more comfortable.
I woould suggest to just use one timer scheduled at the least common divisor.
For example configure your timer to signal every second and you can handle every interval (1 second, 2 seconds, ...) by counting the according number of timer ticks.
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.
One of the analytics that I had to have on my program was How much time do users spend on my program? It is basically a measure of how useful the users find my program that they actively keep on using it. and used to promote users to actively start using the application.
I initially thought of using Time Span between when they start the application to when they close it but the problem was that users could just keep the application open and not use it.
I currently use TotalProcessorTime (C#/VB .Net) to let management know how much time users actively spend on the application. TotalProcessorTime give the amount an application uses the CPU but this does not translate well to management because even when a user actively uses the application for a few minutes the TotalProcessorTime would be far less.
Any out of the box thinking / suggestions?
Since you want to know how much people use your software as opposed to how long your software uses the CPU (they aren't always the same thing), the way I'd do it (and I actually used this before) is to use GetLastInputInfo.
You can have a timer in your application and check every say.. 500ms if your application is the active application and GetLastInputInfo returns the system has been idle for less than some threshold (5-10sec depending on what your application does). As long as both of these two conditions hold, you can add 500ms to your application active usage.
Of course, you can still track total CPU usage as a separate statistic, but I think my way provides a more... focused usage counter for your application.
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.