I\'m writing code that need to run only when there is no human activity on the PC, like when the screensaver is running. Any suggestions on how to do this in c++ under windows?<
The inability to detect user inputs in a service is enforced by design.
That means that a service has, among other things, no direct way of knowing when the last user input occurred, and is the reason why GetLastInputInfo
returns nothing useful when called from within a service.
Apparently the idea was to make life more difficult for rabid hackers trying to write key loggers and other nasty pieces of code.
Of course you can easily bypass that limitation by having a user process feed that information to your service.
I don't suppose this trivial workaround is out of reach of your average rabid hacker, I rather picture the guys relishing in such pretty pointless exercises in code convolution.
If your service performs user-requested computations, you will most likely need a user process to interact with it anyway. But if you want to poll whatever user activity indication, you'll have to leave this user process running. A user demon kept alive to feed an insignificant bit of information to your real demon. Talk about an efficient use of resources...
As a side note, monitoring screen saver activations is pretty unreliable. The screen could be set to shut off before any saver shows up. The PC could also go to sleep before your code get a chance to run. So you'll have to be more careful about what conditions you check.
Alternatively, you might want to look at the performance counters.
They can give you a truckload of informations on CPU load, disk usage, etc.
You could detect a period of low CPU and/or disk activity relatively easily by monitoring these.
The interface is a terrible mess though, and apparently there are yet other security hurdles to jump. I'm not quite sure which service accounts - if any - can access them or if they can do so by default on a typical Windows installation.
You could also activate your code when nobody is logged in. Apparently there is no obvious way of detecting this, but it is doable from within a service.