本文提供一些模板代码用于windows平台下快速给一个程序写个守护程序。
代码:
具体使用步骤:
步骤一:
用vs2008或更高新建一个空的控制台项目。具体步骤不详述,你懂的。
步骤二:
将
WindowsDaemonMain.cpp
WindowsProcess.cpp
WindowsProcess.h
代码添加到刚新建的空项目内。
步骤三:
修改WindowsDaemonMain.cpp内红色部分代码
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef _DEBUG
#define DAEMON_SELF_NAME _T("MYEXE_DAEMOND")
#define BE_DAEMONED_PROCESS_NAME _T("MYEXEd.exe")
#elif defined NDEBUG
#define DAEMON_SELF_NAME _T("MYEXE_DAEMON")
#define BE_DAEMONED_PROCESS_NAME _T("MYEXE.exe")
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////
将4行红字中的MYEXE改成你程序的实际名字。如你的程序叫那个myTest.exe, 则红字部分修改后为
MYTEST_DAEMOND
myTestd.exe(假定此程序的debug版本的exe名为myTestd.exe)
MYTEST_DAEMON
myTest.exe
步骤四:
编译运行测试一下。
说明:
1 以下代码是为了完成将控制台运行的程序后台运行。
#ifdef _UNICODE
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"wmainCRTStartup\"")
#else
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#endif
2
#ifdef _DEBUG
#define DAEMON_SELF_NAME _T("MYEXE_DAEMOND")
#define BE_DAEMONED_PROCESS_NAME _T("MYEXEd.exe")
#elif defined NDEBUG
#define DAEMON_SELF_NAME _T("MYEXE_DAEMON")
#define BE_DAEMONED_PROCESS_NAME _T("MYEXE.exe")
#endif
DAEMON_SELF_NAME的作用是定义一个名字,此名字给函数CreateMutex使用,用于确保守护程序只有一个实例。
BE_DAEMONED_PROCESS_NAME定义了要守护的程序的名字。
3
int _tmain(int argc, _TCHAR* argv[])
{
//ensure only one daemon
HANDLE hMutex = CreateMutex(NULL, FALSE, DAEMON_SELF_NAME);
if (
(hMutex != NULL)
&& (::GetLastError() != ERROR_ALREADY_EXISTS)
)
{
while(1)
{
BOOL bFind = WindowsProcess::FindProcess(BE_DAEMONED_PROCESS_NAME);
if (!bFind)
{
TCHAR sExePath[MAX_FILE_PATH];
int nExePathLength = MAX_FILE_PATH;
memset(sExePath, 0, sizeof(TCHAR)*MAX_FILE_PATH);
WindowsProcess::ExeFileDir(NULL, &nExePathLength);
if (nExePathLength > 0 && nExePathLength < MAX_FILE_PATH)
{
nExePathLength = MAX_FILE_PATH;
WindowsProcess::ExeFileDir(sExePath, &nExePathLength);
_tcscat(sExePath, BE_DAEMONED_PROCESS_NAME);
if (WindowsProcess::StartProcess(sExePath))
{
Sleep(2000);
}
else
{
printf("Start Error!\r\n");
}
}
}
Sleep(1000);
}
}
else
{
printf("Daemon is already running.\r\n");
}
return 0;
}
守护逻辑:
i)确保只有一个守护实例。
ii) 死循环查看进程是否已启动。
未启动,则启动。
已启动,则等待1秒继续监测。
不足:
1 被守护的进程的启动不允许传递控制台命令行参数。(此模版暂不支持)
2 被守护的进程与守护进程必须在同一目录下。(此模版的逻辑就是这么认为的)