I just released, on GitHub, IdleTaskTerminatorLite, my first foray into the lower-level world of programming directly with the Win32 API.
We use an old custom shutdown.exe
(BeyondLogic Shutdown) to provide a timed screen lock feature, where a user is notified their screen will lock in a period of time and can cancel the locking of the workstation.
Clicking the Cancel button within the time limit, however, seems unnecessary and requires precisely clicking the Cancel button when the user is under time pressure! This is not a good user experience. A simple change to the idle state of the machine (any keypress or mouse movement) should cancel the timed locking of the workstation.
This lightweight background application detects user activity and forcibly kills the beyondlogic.shutdown.exe
process, effectively cancelling the locking of the workstation without requiring the user to actually click Cancel.
This is currently rather ‘opinionated’ in that it specifically checks for hard-coded named processes running. It Works for Us(tm), but you may need to modify it for your environment. 😉
This whole solution is a little bit hacky, but it works. 😐
I had written something along these lines to terminate this workstation lock program in C#, but as a .NET process running in the background, you were looking at dozens of megabytes of RAM for something always running in the background. It felt thoroughly inefficient and unnecessary for something so simple.
I have always found myself honestly a little frightened of C and C++. Horror stories around coding securely, the undefined behaviour of doing ‘pointer stuff’ yourself… but this little project represented an opportunity to take this relatively rudimentary functionality and learn how to implement it the Win32 API directly in a C program — and in doing so, cut resource usage (hopefully) significantly.
So, I did. Using the oft-abused WH_KEYBOARD_LL hook (and its WH_MOUSE_LL cousin), I periodically update a counter as to the user’s last idle time. If the hook is called (i.e. the user is typing or moving the mouse) and it’s been long enough since we last noticed such interaction, I check for the beyondlogic.shutdown.exe process and, if present, kill it.
This began life as whatever Visual Studio template gave me a buildable project that let me work with the right APIs, so there is likely unnecessary stuff still present and it could be more lightweight still. And, there’s a good chance I’ve made mistakes that need correcting, so please do get in contact if you’re willing to educate me in some small (or large) way!
I have tried to be particularly careful with buffers — string handling is either done with (I guess, inefficient) fixed-size buffers where I check what I put in will fit first, and I’ve tried to use the ‘safe’ string functions where possible too.
So, it’s a baby step towards working on more low-level projects. But, I’ve taken some action to tackle my pointer anxiety. 🙂
Maybe next the whole program should do the workstation locking, warning message and idle detection in one program.