Problem description:
Our customers want the client program to be online 24 hours a day on the client. If the program crashes or exits due to special reasons, the program should be automatically restarted.
One solution we have come up with is to use a monitoring process, which automatically tries to start the program when it is started, and checks whether the program is still started at intervals, if not, restart the program.
Problem Analysis:
1. First, we can use the following code to start a program on Windows and regularly check the running status of the program:
[Cpp]
# Include <windows. h>
# Include <stdio. h>
# Include <tchar. h>
Void _ tmain (int argc, TCHAR * argv [])
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory (& si, sizeof (si ));
Si. cb = sizeof (si );
ZeroMemory (& pi, sizeof (pi ));
If (argc! = 2)
{
Printf ("Usage: % s [using line] \ n", argv [0]);
Return;
}
// Start the child process.
If (! CreateProcess (NULL, // No module name (use command line)
Argv [1], // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
& Si, // Pointer to STARTUPINFO structure
& Pi) // Pointer to PROCESS_INFORMATION structure
)
{
Printf ("CreateProcess failed (% d). \ n", GetLastError ());
Return;
}
// Wait until child process exits.
WaitForSingleObject (pi. hProcess, INFINITE );
// Close process and thread handles.
CloseHandle (pi. hProcess );
CloseHandle (pi. hThread );
}
2. Perform regular detection and restart the sub-process when the sub-process exits.
3. To ensure that only one sub-process is started at a time, make sure that the program can only be started once. We can implement it using the following code:
[Cpp]
# Ifndef LimitSingleInstance_H
# Define LimitSingleInstance_H
# Include <windows. h>
// This code is from Q243953 in case you lose the article and wonder
// Where this code came from.
Class CLimitSingleInstance
{
Protected:
DWORD m_dwLastError;
HANDLE m_hMutex;
Public:
CLimitSingleInstance (TCHAR * strMutexName)
{
// Make sure that you use a name that is unique for this application otherwise
// Two apps may think they are the same if they are using same name
// 3rd parm to CreateMutex
M_hMutex = CreateMutex (NULL, FALSE, strMutexName); // do early
M_dwLastError = GetLastError (); // save for use later...
}
~ CLimitSingleInstance ()
{
If (m_hMutex) // Do not forget to close handles.
{
CloseHandle (m_hMutex); // Do as late as possible.
M_hMutex = NULL; // Good habit to be in.
}
}
BOOL IsAnotherInstanceRunning ()
{
Return (ERROR_ALREADY_EXISTS = m_dwLastError );
}
};
# Endif
Save the preceding content as LimitSingleInstance. h, and then create an instance at the entrance of the program:
[Cpp]
# Include "LimitSingleInstance. H"
// The one and only CLimitSingleInstance object.
CLimitSingleInstance g_SingleInstanceObj (TEXT ("Global \\{ 9da0beed-7248-440a-b27c-c0409bdc377d }"));
Int main (int argc, char * argv [])
{
If (g_SingleInstanceObj.IsAnotherInstanceRunning ())
Return 0;
// Rest of code.
}
Programming Environment:
Qt 4.7 + Visual Studio 2008