一个后台运行程序的简单设计
来源:互联网 发布:传智大数据百度网盘 编辑:程序博客网 时间:2024/05/16 15:36
很多时候,我们都会遇到编写后台运行程序的问题。编写后台运行程序的主要工作并不在接口上,而是在其作为服务器程序所完成的实际工作上。由于编写过不少后台工作程序,最初总是为程序的后台工作接口而苦恼不已。在这里,我贴出相关的代码,相信根据此设计,读者可以轻易地把它应用到自己的后台程序中去。
假设程序名称为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
#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;
}
#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;
}
- 一个后台运行程序的简单设计
- Linux 程序后台运行的简单方法
- 一个简单的微博后台设计
- 保持python程序后台运行的简单方法
- 开发运行一个简单的perl程序
- 运行一个简单的C#程序
- 一个简单java程序的运行全过程
- 程序转后台运行一个方法
- 简单的S40后台运行
- 一个简单的DELPHI程序注册码设计
- 一个简单的DELPHI程序注册码设计 .
- 自己动手写一个简单的Shell之二:运行程序
- 一个简单程序的创建与运行过程
- Linux下计算程序运行时间的一个简单方法
- dcos - 如何运行一个简单的小程序(docker容器)
- 让控制台程序后台运行并开机启动的简单方法
- 让控制台程序后台运行并开机启动的简单方法
- 让控制台程序后台运行并开机启动的简单方法
- Java数据库存取技术
- scjp证书的收取
- win2000/xp/2003实现自动登录的几种方法
- Java及相关字符集编码问题研究
- oracle触发器实现在归定的时间内不能添加数据
- 一个后台运行程序的简单设计
- Java及相关字符集编码问题研究续
- 将PowerPoint转换为视频的软件——ppt2wmv的使用
- 解析Geodatabase空间参考的工作原理
- ASP.NET Tips
- 将PowerPoint转换为视频的软件——ppt2wmv简介
- 将PowerPoint转换为视频的软件——ppt2wmv系统需求
- 要专一
- "磁盘空间不足"真正原因