很多時候,我們都會遇到編寫后臺運行程序的問題。編寫后臺運行程序的主要工作并不在接口上,而是在其作為服務器程序所完成的實際工作上。由于編寫過不少后臺工作程序,最初總是為程序的后臺工作接口而苦惱不已。在這里,我貼出相關的代碼,相信根據此設計,讀者可以輕易地把它應用到自己的后臺程序中去。
假設程序名稱為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_
#define
?MAX_MSG_SIZE????????????????1500
#define
?MAX_BUFFER_LEN????????????????1024
#define
?MIN_BUFFER_LEN????????????????256
#define
?MAX_FILE_NAME_LEN????????????MAX_BUFFER_LEN
#define
?CFG_PATH????????????????????"Startup.ini"
void
?loadConfig();
void
?mprintf(
const
?
char
?
*
pszFormat,...);

#endif
Startup.cpp
#include?
"
Startup.h
"
#include?
<
stdlib.h
>
#include?
<
Windows.h
>
#include?
<
iostream
>
using
?
namespace
?std;

HANDLE????hExitHandle????
=
?
0
;
HANDLE????hLoadHandle????
=
?
0
;
int
????????nDbgInfoPrt????
=
?
0
;

int
?main(
int
?argc,?
char
*
?argv[])

...
{
????
if
?(argc?
>
?
2
)

????
...
{
????????cout?
<<
?
"
Error,?print?"Startup?-help"?for?usage.
"
?
<<
?endl;
????????
return
?
0
;
????}
????
if
?(argc?
==
?
2
?
&&
?strcmp(argv[
1
],?
"
-help
"
)?
==
?
0
)

????
...
{
????????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
;
????}
????
if
?(argc?
==
?
2
?
&&
?strcmp(argv[
1
],?
"
-v
"
)?
==
?
0
)

????
...
{
????????cout?
<<
?
"
Startup?v1.0?for?starting?up?test
"
?
<<
?endl;
????????
return
?
0
;
????}
????
if
?(argc?
==
?
2
?
&&
?strcmp(argv[
1
],?
"
-d
"
)?
==
?
0
)

????
...
{
????????nDbgInfoPrt?
=
?
true
;
????????mprintf(
"
Run?application?in?debug?mode!
"
);
????}
????
if
?(argc?
==
?
2
?
&&
?strcmp(argv[
1
],?
"
-h
"
?)?
==
?
0
)

????
...
{
????????
//
Run?the?program?background
????????
char
?szPath[MAX_PATH]?
=
?
...
{?
0
?}
;
????????STARTUPINFO?si;
????????PROCESS_INFORMATION?pi;

????????ZeroMemory(
&
si,?
sizeof
(si));
????????si.cb?
=
?
sizeof
(si);
????????ZeroMemory(
&
pi,?
sizeof
(pi));

????????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.
????????????)?

????????
...
{
????????????cout?
<<
?
"
Failed?in?starting?application,?error?code:?
"
?
<<
?GetLastError()?
<<
?endl;
????????}
????????
return
?
0
;
????}
????

????
if
?(argc?
==
?
2
?
&&
?strcmp(argv[
1
],?
"
-k
"
)?
==
?
0
)

????
...
{
????????hExitHandle?
=
?OpenEvent(EVENT_ALL_ACCESS,?FALSE,?(LPCWSTR)
"
StartupKill
"
);
????????
if
?(NULL?
==
?hExitHandle)

????????
...
{
????????????mprintf(
"
Can't?open?kill?event
"
);????????????
????????????
return
?
0
;
????????}
????????SetEvent(hExitHandle);
????????
return
?
0
;
????}
????
if
?(argc?
==
?
2
?
&&
?strcmp(argv[
1
],?
"
-l
"
)?
==
?
0
)

????
...
{
????????hLoadHandle?
=
?OpenEvent(EVENT_ALL_ACCESS,?FALSE,?(LPCWSTR)
"
StartupLoad
"
);
????????
if
?(NULL?
==
?hLoadHandle)

????????
...
{
????????????mprintf(
"
Can't?open?load?event
"
);????????????
????????????
return
?
0
;
????????}
????????SetEvent(hLoadHandle);
????????
return
?
0
;
????}
????hExitHandle?
=
?CreateEvent(NULL,?TRUE,?FALSE,?(LPCWSTR)
"
StartupKill
"
);
????
if
?(NULL?
==
?hExitHandle)

????
...
{
????????mprintf(
"
Can't?create?kill?event
"
);
????????
return
?
0
;
????}
????hLoadHandle?
=
?CreateEvent(NULL,?TRUE,?FALSE,?(LPCWSTR)
"
StartupLoad
"
);
????
if
?(NULL?
==
?hLoadHandle)

????
...
{
????????mprintf(
"
Can't?create?load?event
"
);
????????
return
?
0
;
????}
????
if
?(GetLastError()?
==
?ERROR_ALREADY_EXISTS)

????
...
{
????????cout?
<<
?
"
Application?has?already?started.
"
?
<<
?endl;
????????
return
?
0
;
????}
????
//
?load?the?configure?information
????loadConfig();

????
for
?(?;?;?)

????
...
{
????????
if
?(WaitForSingleObject(hExitHandle,?
0
)?
!=
?WAIT_TIMEOUT)

????????
...
{
????????????
break
;
????????}
????

????????
if
?(WaitForSingleObject(hLoadHandle,?
0
)?
!=
?WAIT_TIMEOUT)

????????
...
{
????????????loadConfig();
????????}
??
????????
//
?TODO:?do?something?here
????????mprintf(
"
The?program?is?alive!
"
);

????????Sleep(
1000
);
????}
????CloseHandle(hExitHandle);
????CloseHandle(hLoadHandle);

????
return
?
0
;
}
/**/
///////////////////////////////////////////////////
//
//
?Description:?load?the?configure?from?.ini?file
//
?
//
?Parameter:?
//
????void?==?
//
//
?Return:
//
????void?==
//

/**/
///////////////////////////////////////////////////
void
?loadConfig()

...
{
????
//
?Get?the?configure?info?from?Startup.ini????
????nDbgInfoPrt?
=
?GetPrivateProfileInt((LPCWSTR)
"
SERVER
"
,?(LPCWSTR)
"
DEBUG
"
,?????
0
,????(LPCWSTR)CFG_PATH);
}
/**/
///////////////////////////////////////////////////
//
//
?Description:?print?the?msg
//
?
//
?Parameter:?
//
????const?char?*pszFormat?==?
//
//
?Return:
//
????void?==
//

/**/
///////////////////////////////////////////////////
void
?mprintf(
const
?
char
?
*
pszFormat,...)

...
{
????
if
?(
!
nDbgInfoPrt)

????
...
{
????????
return
;
????}
????va_list?vaArg;
????va_start(vaArg,?pszFormat);????


????
char
?szDbgInfo[MAX_BUFFER_LEN?
+
?
1
]?
=
?
...
{
0
,?}
;
????vsprintf_s(szDbgInfo,?pszFormat,?vaArg);

????va_end(vaArg);

????cout?
<<
?szDbgInfo?
<<
?endl;
}
?
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1472147