## Vista: Restart Manager

Sat, October 14, 2006, 03:45 AM under Windows | Vista
Intro
It is amazing how as end users we all take for granted that before we install something we need to save our application state, manually close everything, install the new thing, manually restart every app we were using (if we remember what they were) and try to get to the state we were before! How many times have you installed an application (or completed a Windows Update or some other patch) and then had to restart your machine? How irritating is that?

Restart Manager promises to make that experience a thing of the past. Personally, I'd like to live with Vista for a bit longer before I subscribe to that promise but I have to admit initial experiences are promising!

So what does Restart Manager (RM) do?

Fundamentally, when a RM-aware piece of software installs, it will ask all RM-aware applications to shutdown, assuming the said applications are holding resources (e.g. files) that it needs to update. The RM-aware app, will listen to the request and shutdown, saving its state! When the installation has completed, it will then restart all the RM-aware applications. The RM-aware application will then restore its state and the user has a nice experience. The classic example is that you have left Word open with a document you are working on and gone home. Overnight a patch is available and windows update does its job. So it closes down Word, install whatever, then restarts Word so when you arrive in the morning, you can't even tell what happened because Word is waiting for you where you left it with the document you were last working on :)

If the update involves a critical system component so a windows reboot is unavoidable, a reboot will take place but after reboot the RM-aware applications will also restart!

Now that Vista offers this technology, reaching this seemingly imaginary world is down to us, application developers. And since you are reading this blog... managed developers! So what is it we need to do?

Developer actions
Well, reading the above should have given you a clue :)
1. We need to make our installations follow the RM philosophy and
2. we need to make our applications at runtime also play ball

To achieve the first action we can simply use (directly or indirectly via commercial package) Windows Installer v4 and you are pretty much done!! If you have chosen an alternative deployment technology then ditch it and switch! No I am only joking, if you do wish to use something else, then you must manually work with the API which resides in rstrtmgr.dll. A typical series of calls is to create a session (RmStartSession), then register the resources we created (RmRegisterResources), then shutdown the resources/processes (RmShutdown), later on restart them (RmRestart) and finally end the session (RmEndSession). I may post a full C# sample in a future blog entry.

To achieve the second developer action for your application, you need to do a further two things:
a) Register with the system for restart, and be capable of restoring your state when (re)starting up
b) Listen for the message from an installation program that you are about to shutdown (good opportunity to save state etc)

The first of these actions is identical to what we talked about before for unexpected crashes/hangs. Now you see that there is a dual benefit to calling RegisterApplicationRestart as I’ve already mentioned in this article.

The difference with that scenario is that in this case your application doesn't crash, instead it is being asked nicely to shutdown. To listen to that request you need to hook into your window's message loop and listen for a specific message as per the example below:
    protected override void WndProc(ref Message m)    {      base.WndProc(ref m);      if (m.Msg == WM_QUERYENDSESSION) //0x0011      {        if ((m.LParam.ToInt32() & ENDSESSION_CLOSEAPP) == ENDSESSION_CLOSEAPP) //0x1        {          // some installation will shut us down next, so do some cleanup (prepare for it)          File.WriteAllText(Environment.CurrentDirectory + @"\rm.txt", "for demo purposes");          //MessageBox.Show("intercepted", “RM request”);        }      }    }