Click here to Skip to main content
13,198,850 members (42,529 online)
Click here to Skip to main content
Add your own
alternative version


20 bookmarked
Posted 20 Jan 2006

Reanimator utility for process recovery

, 20 Jan 2006
Rate this:
Please Sign up or sign in to vote.
Description of a process recovery utility, which can be considered as a simple example of using multithreading, inter-thread communication, and synchronization techniques.

Sample Image - Reanimator_screenshot.jpg


This article provides the description of a process recovery utility, which was implemented using Visual C++ and MFC. The source code of the utility can be considered as a very simple example of using multithreading, inter-thread communication, and synchronization techniques.


Recently, I had a task of realization of a utility, which would monitor the availability of an application and automatically restart this application in case it was crashed or accidentally closed by the user. The utility had to assure that the application was always running. I decided to create it as a more or less universal tool, which could be used with any kind of application and whose code base could be used in other similar solutions. I called this utility Reanimator.

First, I was going to realize Reanimator using C# and the .NET Framework, as the easiest and the quickest way of doing it (at least for me), but I preferred to avoid forcing the users to install the .NET Framework on their PCs only in order to use this little auxiliary utility. So, it was decided to create it using C++/MFC.

General Description

The main idea of this solution is the following. The user starts the target application, not directly, but through the Reanimator utility, which stores the handle of the started process and then, periodically, checks the availability of the process using the WaitForSingleObject Win32 API function. The checking loop is performed in a separate thread, which I’ll further refer to as the “monitoring thread”. As soon as the monitoring thread detects that the process is not available anymore, it starts the application again using the same command line which was used when the application was started initially, and continues monitoring the process of the started application. All the events of such automatic process recovery are logged to a text log file (Reanimator.log, in the directory of the utility’s executable file) and displayed in the utility’s window, so that the user could track its “reanimation” activity.

Reanimator provides an option allowing automatic startup of the utility when Windows starts (when the Windows user session is started after the user’s logon, to be more precise; HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run key is used for automatic startup of the utility). When Reanimator is automatically started in such a way, it also automatically starts the application, which was previously run using this utility, and begins monitoring the process of this application.

The command line and the status of the automatic startup option are automatically saved (as application settings, which are stored in the current user’s profile) when the utility is closed. Closing the utility doesn’t cause the running application to be stopped, but the application remains running without being monitored, of course.

Internal Implementation (Main Class)

All the process recovery functionality is implemented in the class CReanimatorWorker. This class exposes only two public methods, which are presented below:

// Starts the application, using the command line passed as the parameter,
// and starts the monitoring thread.
// In case of failure throws an exception of CString type with the object containing
// the description of the problem.

void Run(CString &csCmdLine) throw (...);

// Stops monitoring the application (but doesn't terminate the application)

void Stop(void);

In order to use this class, it is enough to create an instance of the class (using its default constructor, which is the only constructor) and call the Run method, passing the command line string for starting (and restarting) the application as an input parameter for this method.

Using the Stop method, it is possible to stop the monitoring thread if it is not needed anymore (for example, when the user wants to close the application without having this application to be automatically restarted by the monitoring thread). Though, it is not necessary to call the Stop method when the CReanimatorWorker object is not needed anymore, because the destructor of this class always stops the monitoring thread if it is running.

Immediately after the monitoring thread detects that the process is absent and tries to restart it, it notifies the main thread (the thread which called the CReanimatorWorker::Run method) about this event, indicating the results of process recovery. The notification is performed by sending a message to the main thread (using the CWinThread::PostThreadMessage method). The ID of the message is exposed by the class CReanimatorWorker as a constant named REANIMATED_MSG_ID:

static const UINT REANIMATED_MSG_ID = WM_USER + 1;

The wParam parameter of the message contains a BOOL value indicating if the process recovery was successful (TRUE) or not (FALSE). In the case of a recovery failure (if the process was not restarted successfully), the lParam parameter represents a pointer to an object of type CString, containing the description of the error which caused the failure. In this case, the monitoring thread is automatically stopped because, usually, the elimination of the cause of the problem would require the intervention of the user anyway, and therefore it's useless to continue subsequent attempts of starting the process. Using this notification mechanism, the main thread can track all the events of the automatic process recovery.

Implementation Notes

  1. After starting (or restarting) the process, the starting procedure waits for a few seconds, and then checks if the process is still available, in order to assure that the process was not terminated immediately after it was started (for example, the cause could be an application initialization failure or something like that). Only if the process remains available after a while, it is considered that the application was started successfully.
  2. The CReanimatorWorker class has a private member variable called m_bStopRequested, which can be accessed by both the main and the monitoring threads. To make the access to this variable thread-safe, the CCriticalSection class is used.
    // critical section for accessing m_bStopRequested,
    // which can be accessed by both
    // the main thread and the worker (monitoring) thread
    CCriticalSection m_critSect;
    // Flag indicating that the worker (monitoring) thread needs to be stopped.
    // IMPORTANT: Must be accessed only using thread-safe helper methods
    // GetStopRequested and SetStopRequested
    bool m_bStopRequested;
    // Thread-safe access to m_bStopRequested
    bool GetStopRequested(void)
        bool bStopRequested = m_bStopRequested;
        return bStopRequested;
    // Thread-safe access to m_bStopRequested
    void SetStopRequested(bool value)
        m_bStopRequested = value;
  3. The Release build configuration of the utility produces an executable which is statically linked with the MFC libraries. This makes it possible to distribute the utility as a single executable file, without the need to bother about any MFC runtime DLLs.


Once, some time ago, I almost began the realization of a similar solution for the recovery of a Windows service application. Fortunately, I timely discovered that such a feature is available as part of the Windows operating system, starting from Windows 2000. So, I didn’t have to “reinvent the wheel”. Normally, applications which are expected to be running constantly in the background are realized as services, and there are no problems with the recovery of such applications. In my case, I had to solve the recovery problem for a common (not service) application, and that was the reason for the realization of this little utility. Who knows, may be someone will face the same problem and will find my utility (or its source code) useful.

Any remarks and comments on the article and the source code are welcome.


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


About the Author

No Biography provided

You may also be interested in...


Comments and Discussions

GeneralJust a note Pin
peterchen21-Jan-06 21:09
memberpeterchen21-Jan-06 21:09 
QuestionRe: Just a note Pin
Maxim Izbrodin22-Jan-06 8:47
memberMaxim Izbrodin22-Jan-06 8:47 
AnswerRe: Just a note Pin
peterchen22-Jan-06 9:08
memberpeterchen22-Jan-06 9:08 
QuestionRe: Just a note Pin
Maxim Izbrodin22-Jan-06 9:21
memberMaxim Izbrodin22-Jan-06 9:21 
AnswerRe: Just a note Pin
peterchen22-Jan-06 9:31
memberpeterchen22-Jan-06 9:31 
GeneralRe: Just a note Pin
Maxim Izbrodin22-Jan-06 9:37
memberMaxim Izbrodin22-Jan-06 9:37 
GeneralRe: Just a note Pin
Blake Miller23-Jan-06 9:58
memberBlake Miller23-Jan-06 9:58 
QuestionRe: Just a note Pin
Maxim Izbrodin22-Jan-06 9:12
memberMaxim Izbrodin22-Jan-06 9:12 
GeneralDoesn't matter how you pass CString to a function Pin
Damir Valiulin24-Jan-06 6:16
memberDamir Valiulin24-Jan-06 6:16 
It doesn't matter how you pass CString, its contents won't be copied unless you call any of it's functions that modify the string. Look at the source code for CString.

Couple of years ago we had an argument with a colleague of mine of what is the best way to pass constant strings to a function. Long time ago I've read in MSDN that it's best to use const CString& rather than LPCTSTR. So he asked Paul DiLasca, the MSDN C++ colunmn guru, this question. Here's what we got back:

From: Paul DiLascia
Sent: Tuesday, July 15, 2003 11:02 AM

It really doesn't matter--in fact you can just pass them as CString's (no
reference) since they only take about 8 bytes. The only reason I can think of
to prefer LPCTSTR is it's more versatile: it lets you pass a char* or CString.

And the original e-mail with the question:

From: #######
To: MSDNMag - C++ Q+A
Sent: Tuesday, July 15, 2003 10:47 AM

Subject: passing cstrings to functions (re: your previous article)


Firstly, I would like to say I enjoy reading your column.

Now for my question...

We were wondering if CStrings should be passed to functions as "LPCTSTR" or
as "const CString&". I know you've dealt with this issue before (in the August
1996 MSJ), but I was wondering if your column is still valid. (I was thinking
Microsoft might have changed something since you wrote your column).

If you're column is still valid, then I guess I'm wondering why the most recent
MSDN link (7 years after your column) still recommends passing as LPCTSTR?

August 1996 MSJ:

MSDN Home > MSDN Library > Strings in MFC > Strings: CString Argument Passing

Any ideas or advice would be welcome.


GeneralRe: Doesn't matter how you pass CString to a function Pin
peterchen24-Jan-06 8:20
memberpeterchen24-Jan-06 8:20 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.171020.1 | Last Updated 20 Jan 2006
Article Copyright 2006 by Maxim Izbrodin
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid