旅途

如果想飞得高,就该把地平线忘掉

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

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

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

posted on 2007-08-09 00:49 旅途 阅读(1692) 评论(0)  编辑 收藏 引用 所属分类: 深入windows


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理