[ Go to June 1997 Table of Contents ]

Power Windows /
Karen Kenworthy
Karen Kenworthy

Do the Shutdown Shuffle
You can automatically wake up certain programs before putting Windows to sleep.

Download PWSHUT.ZIP.

Since Windows 3.1, you've been able to make programs run automatically each time Windows starts. With Win3.1, you placed "Program Items" in the old Program Manager's StartUp group. With Windows 95, you can place shortcuts to programs in the StartUp folder.

That works fine for those who like to do everything early. You know who you are. When you wake up in the morning, every hair's already in place. And a cup of coffee would make you too perky.

But what about us slow starters who put everything off until the last minute? What we need is a Shutdown group, a way to run programs automatically just before Windows exits. For us, I wrote PWShut, the WinMag Shutdown group. It's available from any of WinMag's download locations (listed in the table of contents)

PWShut is easy to use. First, create a directory named Shutdown within your Windows 95 directory. For example, if Windows is installed in C:\WINDOWS, create a directory named C:\WINDOWS\SHUTDOWN.

Inside this new directory, create shortcuts to the programs you'd like run just before Windows exits. These might take care of system maintenance, put time stamps on documents, perform housekeeping chores while cleaning out temp files or check on whether a certain program is still running. You can store executable files, such as EXE, COM and BAT files, in the Shutdown directory. BAT files can be useful when a group of programs or DOS commands must be run in a particular order. Just list the commands in your desired order within the batch file. Precede each batch file line with Start /wait to ensure that each command finishes before the next one starts. For example, to run a program named XYZ.EXE, the batch file line would look like this: Start /wait XYZ.EXE.

Both batch files and shortcuts have properties that you may want to edit. To do so, right-click on the shortcut or batch file's icon, then select Properties from the Context menu. The more useful shortcut properties include Target and Run, both on the Shortcut tab of the Properties dialog. Target specifies the full command used to launch the shortcut's program, including any command-line parameters. The Run property determines the size of the program's initial window (Maximized, Minimized or Normal)

Batch files have a Run property, too, found on the Program tab of the batch file's Properties dialog. The same tab of the dialog contains the Cmd Line property, which is the full name of the batch file, followed by any command-line parameters it needs. Another useful batch file property is the Close on Exit checkbox. When checked, Close on Exit causes the batch file's window to disappear after all its commands have been executed. If this box isn't checked, you'll probably have to manually close the batch file's window after each run.

Once you store everything safely in the Shutdown directory, place a copy of PWSHUT.EXE in your Windows directory and a shortcut to it in your StartUp group.

Now when Windows starts, a copy of PWShut will automatically load. Until you ask Windows to exit, PWShut will sit quietly, showing just an icon on your taskbar. But when you order Windows to shut down, PWShut flies into action.

PWShut's first act is to cancel the pending shutdown (more about that later). Then, PWShut scans your Shutdown directory and executes each program and batch file it finds. It runs each program in the order it finds them, one at a time. That means a new program doesn't start until the previous program finishes. Once all the programs in your Shutdown group finish, PWShut finally causes Windows to exit.

Debugging

PWShut provides one feature the Windows StartUp folder lacks. Normally, PWShut works invisibly. But if you execute it with the command-line parameter /debug, it will display its main window as it processes the Shutdown directory. As you can see in the sidebar, "A Real Turnoff," the main window includes a list box that displays PWShut's progress.

The first line displayed tells us that PWShut is operating in Debug Mode and waiting for Windows to initiate a shutdown. Once the shutdown is requested, PWShut tells us which directory it is scanning (usually C:\WINDOWS\SHUTDOWN), then displays one line for each program it runs. If a program can't be executed, you'll see an additional line that states [Program name] Failed.

The /debug parameter also alters PWShut's behavior in another useful way. While running in Debug mode, PWShut will not let Windows shut down. That makes it a lot easier to run multiple tests.

We've already peeked inside PWShut's bag of tricks. Back in January 1996 we described a Power Windows utility named PWScan that showed how a program could discover the contents of a directory. We used the same technique in the Matchmaker utility (See Power Windows, May). We've also seen how one program can launch another, most recently in January when examining PWOne, the WinMag Instance Limiter. But PWShut has a few tricks of its own. Let's take a moment and look at one of the more interesting ones.

Back when I was in school, you could get into a lot of trouble for doing what Windows does thousands of times a day. Windows is notorious for passing messages. Windows applications need these electronic missives to know when you've pressed a key, moved or clicked your mouse, or when you want to shut down Windows.

Windows passes these messages to your program by calling a message handler, a special function written for just this purpose. This function accepts four parameters: a window handle, a message ID, lParam and wParam. The window handle is a number that identifies the window affected by the message. A message ID is a single 16-bit number that defines the type of message being sent. The last two parameters, lParam and wParam, often provide the message handler with additional information related to a message.

One Windows message, which is called WM_QUERYENDSESSION, is of special interest to PWShut. It is sent to all running Windows applications whenever a user or another application orders Windows to shut down, or whenever a user asks to log off. This warning message alerts programs to save files and wrap up their work.

Now, remember that message handlers are functions. This means they return a value to Windows after processing each message. In the case of WM_QUERYENDSESSION, if all programs' message handlers return a non-zero value, the shutdown or log-off will take place as requested. But if even one message handler returns a value of zero, it cancels the shutdown.

That's exactly how PWShut responds to the first WM_QUERYENDSESSION message it receives. It returns a value of zero, preventing the shutdown. This reprieve allows PWShut to scan your Shutdown directory and run all the programs it finds. Once that job is done, PWShut calls a special Windows function named ExitWindows to trigger a second shutdown attempt. This time around, PWShut doesn't veto the shutdown, allowing it to take place if all other running applications concur.

You may be wondering why PWShut doesn't just do all its work within its message handler after receiving the WM_QUERYENDSESSION message, but before returning a value to Windows. If our program could get all its work done there, it wouldn't need to block the first shutdown attempt, then initiate a second attempt. Unfortunately, this plan won't work for several reasons.

First, Windows does its best to prevent new programs from being launched once WM_QUERYENDSESSION messages have been sent. Windows hides all icons and disables the Desktop (makes it ignore mouse clicks and keystrokes), effectively preventing you from launching a new program. A running program, like PWShut, can still start another program. But the new program won't run until the parent program finishes. This prevents PWShut from launching more than one program in the Shutdown group and defeats its efforts to monitor launched programs as they run.

Windows plays one other nasty trick on programs that have received a WM_QUERYENDSESSION message. If the program's message handler doesn't respond in a reasonable amount of time (usually about 30 seconds), Windows will exit anyway. Since there's no way PWShut can guarantee all the programs in the Shutdown group will finish within 30 seconds, Windows might disappear before all shutdown processing is complete.

Rough edges

PWShut does its job well, but like most new programs, it has a few rough edges. For now, all users of a PC share a common Shutdown directory. This means the work done at shutdown is the same, regardless of who's logged on. This problem could be fixed by having PWShut ask Windows for the name and directory of the currently logged-on user. PWShut could then search a user's private Shutdown directory, in the same way Windows accesses an individual user's StartUp directory.

The many flavors of shutdowns also pose a problem. Under Windows 95, you can log off, restart the computer, restart the computer in MS-DOS or simply shut down Windows.

PWShut doesn't always know what type of shutdown to request when calling ExitWindows. In the current version, it asks for a log-off if that's what the user originally requested and asks for a restart of Windows in all other cases. Fortunately, it's perfectly safe to turn off the computer during a restart, as long as it's done during the BIOS POST phase (while the memory size is being calculated and so on). We can smooth these rough edges with some tweaking. Look for that to happen in a future version of PWShut. In the meantime, download the program, have a few cups of coffee and give it a try.

Karen Kenworthy is the author of Visual Basic for Applications, Revealed! (Prima Publishing, 1994), a nonprogrammer's introduction to VBA. She is also a contributing editor to WINDOWS Magazine and the manager of WINDOWS Magazine Online on America Online and CompuServe. Reach Karen care at the e-mail address here.


Windows Magazine, June 1997, page 267.

[ Go to June 1997 Table of Contents ]