问题描述:
我们的客户希望客户端程序在客户端上24小时在线,如果因为特殊的原因而崩溃或者退出,应该能自动的重启程序。
我们所想到的一个解决办法就是使用一个监控进程,这个进程一开机的时候就会自动尝试着启动程序;并且,每隔一段时间就检查程序是否还启动着,如果不是的话,则重新启动程序。
问题分析:
1、首先,是如何在Windows上启动一个程序,并定时的检查程序的运行状态,我们可以用如下的代码来做这些事情:
#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 [cmdline]\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、然后需要定期的检测,并且在子进程退出的时候重新启动子进程即可。
3、为了确保同一时间只有一个子进程被启动着,需要确保程序只能启动一次,我们可以用如下的代码实现:
#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 for
//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
将上述内容保存为LimitSingleInstance.h,然后在程序的入口处创建其一个实例:
#include "LimitSingleInstance.H"
// The one and only CLimitSingleInstance object.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{9DA0BEED-7248-450a-B27C-C0409BDC377D}"));
int main(int argc, char* argv[])
{
if (g_SingleInstanceObj.IsAnotherInstanceRunning())
return 0;
//Rest of code.
}
编程环境:
Qt 4.7 + Visual Studio 2008
参考资料:
1、 http://support.microsoft.com/kb/243953
2、 http://stackoverflow.com/questions/1591342/how-to-determine-if-a-windows-process-is-running
3、 http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx
4、 如何创建进程:http://msdn.microsoft.com/en-us/library/ms682512%28VS.85%29.aspx