一个后台运行程序的简单设计

很多时候,我们都会遇到编写后台运行程序的问题。编写后台运行程序的主要工作并不在接口上,而是在其作为服务器程序所完成的实际工作上。由于编写过不少后台工作程序,最初总是为程序的后台工作接口而苦恼不已。在这里,我贴出相关的代码,相信根据此设计,读者可以轻易地把它应用到自己的后台程序中去。

假设程序名称为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;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值