Solution Space: Unexpected Shutdown

You’re in the middle of finishing up an important document, using reference materials scattered across browser tabs, open PDFs, and an email chain — and your computer shuts down.

Whether due to system error or a scheduled mandatory upgrade, unexpected shutdowns represent an exorbitant pain for any user — doubly for so-called “power users” who tend to have dozens of windows and consoles open simultaneously. Losing that context on shutdown can throw you off your game, and cost significant time to get back on track.

Managing this issue differs by system; for instance, macs have a decent feature for reopening windows and programs after a shutdown. What about Windows users? Windows does include a feature to resume open programs on startup, but it’s buggy, inconsistent, and often won’t resume unsaved items the way mac does (even on mac, to be fair, the feature is not perfect).

For me, leveraging a windows/linux dual boot, it’s a big deal. I often switch back and forth between each OS, which requires a shutdown (hibernate is an option — but doesn’t always work cleanly).

After one nuisance of a Blue Screen of Death during the middle of a recording session, I decided to solve this problem for myself.

* * *

As I sat down to think about how to fix this, I realized it can’t be one of my bigger projects. A relatively rare problem, it’s not worth it to spend long hours coding a custom solution to tie into the Windows APIs and work 100% perfectly to all my needs.

What I want is something simple — a list of open windows, so that if my open programs fail to resume after a shutdown, I can read off a list of previously open windows and identify what is missing. A matter of moments.

But how to get there? The key factors are as follows:

1 ) Easy to build. I don’t want to spend hours coding. This means either applying an existing solution, or using a point-and-click interface.

2 ) Windows compatibility. Windows has its own APIs for window management, whereas a more universal solution might not work consistently.

3 ) Readable output. I opt to forgo a more complex solution to actually reopen my programs, which in any case might conflict with Window’s own feature to do this. Instead, I just want a list — but that list should be pretty clear so I can see what I’m missing.

What tool or framework meets the criteria noted above?

It’s time to dig out a name I hadn’t thought about in years: AutoIt.

Rather than trying to describe it myself, I’ll let AutoIt’s site do the talking:

AutoIt v3 is … designed for automating the Windows GUI and general scripting … to automate tasks in a way not possible or reliable with other languages.

Most pertinently, AutoIt is simple, works out-of-the-box, and has lots of Windows API tie-ins that make scripting a breeze. It’s not common that I run across an aspect of my daily workflow that requires this kind of automation, so it’s been a while since I’ve used it! But it’s such a simple setup that in literally two minutes, I’ve got it up and running again.

Before I can be sure that AutoIt will fit my needs, it’s important to check how hard it will be to get a list of open windows…

…fortunately, StackOverflow, via a quick Google search, has done the hard work for me.

I try this script out in AutoIt and find that it works. However, it outputs to console, and I need a written list that I can reference. Jumping into the AutoIt documentation, a quick text search in the function reference leads me to a way to write to a file, including a handy example.

It’s a matter of moments to rewrite my script to output to a file using the new example rather than writing to console. I test the script, and it works! I have a document containing a list of all open windows — just what I want.

Now I’m 90% of the way to a solution, but I’m missing one crucial element: the script needs to be run manually, which doesn’t help me if the computer shuts itself down while I’m not looking.

Fortunately, Windows has a way to schedule processes to run automatically via the task scheduler.

I set up a new task which repeats every hour on the hour — you could change this to a different period of time depending on your needs; for me, an hour is about right. Now it just needs something to run. I could have it run the AutoIt script runner and take the script as a parameter, but there’s a cleaner way: AutoIt provides a utility to turn a script into an executable program!

In a matter of moments, I have an executable file that I can set as the action of my new task in the task scheduler.

And we’re done! In something like ten minutes, I went from identifying a nagging problem, through some very basic analysis, to generating a solution. It’s small, it’s easy, it’s not at all demanding on my system’s resources, and now I won’t have to worry about losing control of my open workflow.

Potential Improvements

  • As you might notice if you followed along in practice, the list of windows that gets written to the document includes all the open background tasks, and many redundancies, so that the end list can prove difficult to peruse, and makes for unsightly reading, cluttered with unnecessary information. Paring this down, either via AutoIt’s WinList or an external means like a regex via PowerShell, would lead to a more effective solution.
  • I find my list of open windows really useful, but it would be much more useful to have them open by themselves. AutoIt could almost certainly handle this, but for me, it wasn’t quite worth the effort. By turning off Window’s automatic restoring feature, you could avoid any conflicts, and use only your own solution to restore your workflow.
  • Because a new document is generated every hour, the list will quickly grow and grow. I currently have the documents output to their own subfolder, and they’re fairly small so I don’t need to worry about space constraints, but it would be nice to have a rolling “cleanup” that gets rid of any documents older than, say, thirty days.

Discussion

As problems go, this was a minor one. As solutions go, I got lucky that such a simple answer could be pulled together. But large or small, the key aspects of solving any such problem generally fall into three categories:

1) Identifying the key problem, and the scope. For me, this meant trading off time for a simpler solution, and realizing what would meet my needs.

2) Awareness of the solution space. There are many ways to solve a problem, but for me, for this issue, AutoIt was the way to go. If I hadn’t known about AutoIt, I might have had a harder time coming up with a solution. However, you can usually preempt such trouble, by—

3) Gathering information efficiently. Once on the trail of the solution, being able to find enough information to build a picture of how to solve the problem is a critical skill, and one that can definitely be developed. In this day and age, Google and other tools often make it child’s play to come up with a mountain of relevant information, such that it’s more important to be able to filter out bad information than to locate good information. But either way, and no matter the means by which you compile the information, thinking critically about what information will lead you on the right path without restricting your vision too narrowly is how you navigate efficiently to a solution.