很多时候,我们都会遇到编写后台运行程序的问题。编写后台运行程序的主要工作并不在接口上,而是在其作为服务器程序所完成的实际工作上。由于编写过不少后台工作程序,最初总是为程序的后台工作接口而苦恼不已。在这里,我贴出相关的代码,相信根据此设计,读者可以轻易地把它应用到自己的后台程序中去。
假设程序名称为startup,那么程序启动的接口为:
Startup: 启动该程序
Startup -v: 查看该程序的版本
Startup -d: 启动该程序,并将调试信息打印到debug文件中
Startup -h: 以后台方式启动应用程序
Startup -k: 停止后台应用程序的运行
Startup -l: 重新读取应用程序的配置文件
配置文件(startup.ini)的格式如下:
[SERVER]
DEBUG = 1
完整的实现如下:
Startup.h
#ifndef _STARTUP_H_
#define
_STARTUP_H_
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
MAX_MSG_SIZE 1500
#define
MAX_BUFFER_LEN 1024
#define
MIN_BUFFER_LEN 256
#define
MAX_FILE_NAME_LEN MAX_BUFFER_LEN
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#define
CFG_PATH "Startup.ini"
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
loadConfig();
void
mprintf(
const
char
*
pszFormat,...);
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#endif
Startup.cpp
#include
"
Startup.h
"
#include
<
stdlib.h
>
#include
<
Windows.h
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
#include
<
iostream
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using
namespace
std;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
HANDLE hExitHandle
=
0
;
HANDLE hLoadHandle
=
0
;
int
nDbgInfoPrt
=
0
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main(
int
argc,
char
*
argv[])
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
if (argc > 2)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
cout << "Error, print "Startup -help" for usage." << endl;
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (argc == 2 && strcmp(argv[1], "-help") == 0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
cout << "Usage: Startup for starting up test." << endl;
cout << "-------------------------------------------" << endl;
cout << "Startup: Start the application." << endl;
cout << "Startup -v: View the version." << endl;
cout << "Startup -d: Start the application in debug mode." << endl;
cout << "Startup -h: Start the application in hide mode." << endl;
cout << "Startup -k: Stop the application running in hide mode." << endl;
cout << "Startup -l: Reload the config when running in hide mode." << endl;
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (argc == 2 && strcmp(argv[1], "-v") == 0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
cout << "Startup v1.0 for starting up test" << endl;
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (argc == 2 && strcmp(argv[1], "-d") == 0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
nDbgInfoPrt = true;
mprintf("Run application in debug mode!");
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (argc == 2 && strcmp(argv[1], "-h" ) == 0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//Run the program background
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
char szPath[MAX_PATH] = ...{ 0 };
STARTUPINFO si;
PROCESS_INFORMATION pi;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
GetModuleFileName(NULL, (LPWCH)szPath, MAX_PATH);
if (!CreateProcess(NULL, // No module name (use command line).
(LPWSTR)szPath, // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
CREATE_NO_WINDOW, // 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.
)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
cout << "Failed in starting application, error code: " << GetLastError() << endl;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (argc == 2 && strcmp(argv[1], "-k") == 0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
hExitHandle = OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPCWSTR)"StartupKill");
if (NULL == hExitHandle)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
mprintf("Can't open kill event");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
SetEvent(hExitHandle);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (argc == 2 && strcmp(argv[1], "-l") == 0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
hLoadHandle = OpenEvent(EVENT_ALL_ACCESS, FALSE, (LPCWSTR)"StartupLoad");
if (NULL == hLoadHandle)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
mprintf("Can't open load event");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
SetEvent(hLoadHandle);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
hExitHandle = CreateEvent(NULL, TRUE, FALSE, (LPCWSTR)"StartupKill");
if (NULL == hExitHandle)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
mprintf("Can't create kill event");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
hLoadHandle = CreateEvent(NULL, TRUE, FALSE, (LPCWSTR)"StartupLoad");
if (NULL == hLoadHandle)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
mprintf("Can't create load event");
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (GetLastError() == ERROR_ALREADY_EXISTS)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
cout << "Application has already started." << endl;
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// load the configure information
loadConfig();
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
for ( ; ; )
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
if (WaitForSingleObject(hExitHandle, 0) != WAIT_TIMEOUT)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
break;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (WaitForSingleObject(hLoadHandle, 0) != WAIT_TIMEOUT)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
loadConfig();
}
// TODO: do something here
mprintf("The program is alive!");
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
Sleep(1000);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
CloseHandle(hExitHandle);
CloseHandle(hLoadHandle);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
///
//
//
Description: load the configure from .ini file
//
//
Parameter:
//
void ==
//
//
Return:
//
void ==
//
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
///
void
loadConfig()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
// Get the configure info from Startup.ini
nDbgInfoPrt = GetPrivateProfileInt((LPCWSTR)"SERVER", (LPCWSTR)"DEBUG", 0, (LPCWSTR)CFG_PATH);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
///
//
//
Description: print the msg
//
//
Parameter:
//
const char *pszFormat ==
//
//
Return:
//
void ==
//
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
///
void
mprintf(
const
char
*
pszFormat,...)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
if (!nDbgInfoPrt)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
va_list vaArg;
va_start(vaArg, pszFormat);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
char szDbgInfo[MAX_BUFFER_LEN + 1] = ...{0, };
vsprintf_s(szDbgInfo, pszFormat, vaArg);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
va_end(vaArg);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout << szDbgInfo << endl;
}