Click here to Skip to main content
Click here to Skip to main content

How To Create a Self-Restartable Application

By , 21 Aug 2006
 
Application Before Restart
Step 1. Application Before Restart
Application While Restarting
Step 2. Application While Restarting
Application After Restart
Step 3. Application After Restart

Introduction

In some cases, your application must be restarted to apply some changes. For example, you might want to restart an application after downloading newer versions of files or changing the UI language of the application. For users, it is very convenient not to have to restart an application manually. The best way is to ask the user if the application has to be restarted then or later.

In this article, I describe an easy way to complete this task with a few lines of code.

Using the code

Using the restart code is very simple.

First, include "RestartAPI.h" in your "stdafx.h", and add "RestartAPI.cpp" in your VC project.

The second step is modifying your main or WinMain function like shown below. Another way is to add the restart initialization code to your application start point and add the restart finishing code to the exit point, such as PreMessageLoop/PostMessageLoop in a WTL application. Here is an example of the modified WinMain function.

int WINAPI _tWinMain(HINSTANCE hInstance, 
           HINSTANCE /*hPrevInstance*/, 
           LPTSTR lpstrCmdLine, int nCmdShow)
{
    // Initialize restart code
    // Check if this instance is restarted and 
    // wait while previos instance finish
    if (RA_CheckForRestartProcessStart())
        RA_WaitForPreviousProcessFinish();
    //
    //
    // Your WinMain Code here
    //
    //
    // Finish restarting process if needed
    RA_DoRestartProcessFinish();
    return 0;
}

The third step is to determine the point where you want to initialize the restarting of an application. In the attached sample, this point is Click handler of the button "Restart Me!". For restarting the application, you must call the RA_ActivateRestartProcess function and terminate your application.

LRESULT CMainDlg::OnBnClickedRestart(WORD /*wNotifyCode*/, 
        WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
    // Initialize restart proceess
    if (!RA_ActivateRestartProcess())
    {
        ::MessageBox(NULL, _T("Something Wrong"), 
                     _T("Restart App"), 
                     MB_OK|MB_ICONEXCLAMATION);
        return 0;
    }
    // Terminate application.
    CloseDialog(IDC_RESTART);
    return 0;
}

Short functions reference

Macro

Command line switch for restarting the application:

#define RA_CMDLINE_RESTART_PROCESS    TEXT("--Restart")

You can redefine the command line switch for your purposes. Restarted application is started with this switch:

#define RA_MUTEX_OTHER_RESTARTING    TEXT("YOUR_RESTART-MUTEX_NAME")

Mutex unique name

Named mutex is used for waiting termination of the first instance of a process. The mutex name must be unique. For that, you can use GUIDs to define mutex namea like this:

#define RA_MUTEX_OTHER_RESTARTING 
        TEXT("APPRESTART-E476AE82-AA92-11DA-ACE4-006098EFC07C")

You can redefine a mutex name for your purposes.

Functions

BOOL RA_CheckProcessWasRestarted();

Returns TRUE if process was restarted.

BOOL RA_CheckForRestartProcessStart();

Checks the process command line for restart switch. Call this function to check that it is a restarted instance.

BOOL RA_WaitForPreviousProcessFinish();

Wait till the previous instance of the process is finished.

BOOL RA_DoRestartProcessFinish();

Call it when a process finishes.

BOOL RA_ActivateRestartProcess();

Call this function when you need to restart an application. Start another copy of the process with the command line RA_CMDLINE_RESTART_PROCESS. After calling RA_ActivateRestartProcess, you must close an active instance of your application.

Downloads

Demo project

The demo project includes a sample WTL dialog application that demonstrates how to use the restarting API. From the screenshots, you can see some stages of the application at work.

The first screen shows the application starting normally. In the second screen, the user clicked the "Restart Me!" button and you see the pseudo-termination progress. If you run the Task Manager at that moment, you'll see two instances of RestartableApp.exe. In the last screen, the application is in the normal state after it was restarted.

Source files

Source files include "RestartAPI.h" and "RestartAPI.cpp" which can be used separately in your Win32 application.

History

  • 10th August 2006
    • Initial public release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Alexander D. Alexeev
Software Developer (Senior)
Russian Federation Russian Federation
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberANewCoder8-Nov-12 4:55 
Thank you for writing this. It took 10 minutes to add and test. Saved me a couple of hours writing and testing code to do the same thing.
GeneralSuperb!memberBuzzLightyear4-Sep-12 22:55 
Exactly what I needed. Roll eyes | :rolleyes:
QuestionA switch in the command line is really needed?memberMember 382240012-Jun-10 4:16 
Is there any way that does not require switch in the command line?
GeneralATLmemberjorgento200917-Feb-10 22:49 
Hi,
 
Do I have to install the Windows SDK so that atlbase.h and all atl libraries can be recognised?
If so, where can I donwload it?
 
Thanks,
 
Jorge
Programmed to programm!
Smile | :)

GeneralRe: ATLmemberAlexander D. Alexeev18-Feb-10 0:50 
Hi,
 
atlbase.h is part of the ATL library and I think that it has been included with Platform SDK.
But other ATL headers shipped only with Visual Studio.
To build sample application you need full Visual Studio.
But library use only Platform SDK headers and funtctions and you can use it with any Win32 compiler and Platform SDK library
 
Alexander.
QuestionRestart exe and Samba symlinks problemmemberkintz21-Jan-07 22:26 
Hi there,
 
We are using the code in this article to restart an application with the aim of it launching an updated exe. We place the exes on a linux box and use symlinks to "update" the version users see
 
The process is as follows:
 
1) Build new exe
2) Put the exe on the server under the folder "application name_developer/version number/app.exe"
3) We then repoint the symlink for a folder "application name" to point to the new version number folder.
4) We then signal the applications already running to close down and restart.
 
So for example if the application is version 1.0.0 and the new one is version 1.0.1 we would expect 1.0.0 to close down, then restart and the restarted version to be 1.0.1 due to the symlink magic.
 
However this does not happen and we still see version 1.0.0 running.
 
Additional info:
The machines running the app are windows boxes.
Samba is restarted on the linux box after the symlink update.
 
Any help on how to get this process to work would be really welcome!
 
Thanks.
QuestionRestart Application after *.exe updatedmemberX-View2-Dec-06 19:53 
Hi,
 
thanks for the tutorial of the Self-Restartable Application.
I want to let my app.exe self-restartable after app.exe updated.
Now I met a big problem that I can't updated my app.exe when it's running.
 
Do you have any idea for this, thanks.
 
XView.
 

AnswerRe: Restart Application after *.exe updatedmemberAlexander D. Alexeev4-Dec-06 2:17 
Hi XView!
 
I think you can use some ideas from this article.
I don't know how to update running application from itself. But I think that's simple to create another UpdateApp.exe, which can update your main.exe.
For your task you must change some source code of this article.
First. In RA_ActivateRestartProcess you must start not your main.exу again, but UpdateApp.exe.
Second. In UpdateApp.exe you must wait until your main.exe procss finish. You can use RA_WaitForPreviousProcessFinish()for this task.
Third. After UpdateApp.exe finish its work for updating main.exe your can start main.exe again with any parameters you want.
 
I don't realize this ideas, but I think it must be not so difficult to code.
 
Best regards Alexander.
QuestionWhat if something hangs?memberHokei29-Aug-06 17:27 
I like the idea. But, what if the first instance hangs or crashes? Will the "replacement" instance be able to start or will it get stuck waiting on the mutex to be released?
AnswerRe: What if something hangs?memberAlexander D. Alexeev29-Aug-06 21:13 
If the first instance crashes everything will be OK. Mutex released when process terminates.
If the first instance hangs, restarted instance will wait for mutex release. But I don't know universal behavior for this situation.
I think there are two ways.
First. Check code of exiting part for deadlocks situations. Make this part very simple, and make this part with impossibility of hangs.
Second. Replace the INFINITY parameter of ::WaitForSingleObject(g_RA_hMutexOtherRestarting, INFINITE); inside RA_WaitForPreviousProcessFinish() with some delay value and ask user if delay is timed out.
If you have any other suggestions let me know please, I think that will be usefull for other people too.
GeneralRe: What if something hangs? [modified]memberHokei31-Aug-06 10:52 
Ok, WaitForSingleObject() with a timeout when trying to acquire the mutex will work fine.
Smile | :)
As a second step, the code might do the following:
(a) try to grab the mutex, with a timeout, using WaitForSingleObject()
(b) if (a) fails (times out), see if the original process is "not responding" and offer (to the user) to kill the unresponsive process. Apparently (I have not tried it yet) this is possible using the GetProcessByName() API and checking something in the structure it returns. See http://support.microsoft.com/kb/304991/EN-US/
 

-- modified at 17:00 Thursday 31st August, 2006
 
The above API was for C#/.NET code only. Here is an equivalent for C/C++ code.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/messagesandmessagequeues/messagesandmessagequeuesreference/messagesandmessagequeuesfunctions/sendmessagetimeout.asp
 
And it occurred to me that since the function only detects if an application is calling GetMessage() or not, it can't really tell if a console application is responding or not.
GeneralRA_WaitForPreviousProcessFinish function namemember_FRED_18-Aug-06 1:44 

// Wait till previous instance of process finish
BOOL RA_WaitForPreviousProcessFinish();

AnswerRe: RA_WaitForPreviousProcessFinish function namememberAlexander D. Alexeev21-Aug-06 4:18 
Thanks!
Article and source will be updated soon.
QuestionIs it possible to use the code in MFC?memberjalal_haddad16-Aug-06 21:12 
Is it possible to use the code in MFC saftly?, and how.
Kindly Explain.
 
Jalal Al Haddad
AnswerRe: Is it possible to use the code in MFC? [modified]memberAlexander D. Alexeev16-Aug-06 21:45 
Yes. It's very simple.
 
Step 0.
Add To your stdafx.h:
 
// if you don't include shlwapi.h include next two lines
#include "shlwapi.h" 
#pragma comment (lib, "shlwapi.lib")
// This line needed
#include "RestartAPI.h"
 
Step 1.
Add at begin of CYourApp::InitInstance() (may be first lines of it)
	
  if (RA_CheckForRestartProcessStart())
    RA_WaitForPreviosProcessFinish();
 
Step 2.
Add CYourApp::ExitInstance() if it absent
at end of CYourApp::ExitInstance() add something like this:
...
  int nRes = CWinApp::ExitInstance();
  RA_DoRestartProcessFinish();
  return nRes;
} // End of CWinApp::ExitInstance();
 
Step 3.
Add next code at point where you need to initiate restart process
if (!RA_ActivateRestartProcess())
{
  // Handle restart error here
  return;
}
// For example post WM_CLOSE to your main window, or 
// do something other work, that terminates your application
PostMessage(WM_CLOSE);
 
That's all you need!
 
PS.
And don't forget to add RestartAPI.h and RestartAPI.cpp to your project
-- modified at 4:54 Thursday 17th August, 2006
GeneralRe: Is it possible to use the code in MFC?memberPiccinano17-Aug-06 9:28 
Good work!
Thanks.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130617.1 | Last Updated 21 Aug 2006
Article Copyright 2006 by Alexander D. Alexeev
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid