windows nt service 架構

來源:互聯網
上載者:User
// Service.cpp : Defines the entry point for the console application.
//

//服務程式主函數。

#include "stdafx.h"

#include "Windows.h"

#define SZAPPNAME      "serverSample"     //服務程式名

#define SZSERVICENAME  "serviceSample"    //識別服務的內部名

//內部變數

bool                   bDebugServer=false;

SERVICE_STATUS              ssStatus;

SERVICE_STATUS_HANDLE  sshStatusHandle;

DWORD                       dwErr=0;

TCHAR                       szErr[256];

//下面的函數由程式實現

void  WINAPI  Service_Main(DWORD dwArgc, LPTSTR *lpszArgv);

void  WINAPI  Service_Ctrl(DWORD dwCtrlCode);

void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv);//具體服務的初始化入口函數

void installService();

void removeService();

void debugService(int argc,char** argv);

bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint);

void AddToMessageLog(LPTSTR lpszMsg);

//int _tmain(int argc, _TCHAR* argv[])
int _tmain(int argc, TCHAR* argv[])

{   

    SERVICE_TABLE_ENTRY dispatchTable[]=
    {

        {TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},

        { NULL,NULL}

    };

    if((argc>1)&&((*argv[1]=='-')||(argv[1]==TEXT("/"))))

    {

        if(_tcsicmp(TEXT("install"),argv[1]+1)==0)

        {

            installService();

        }

        else if(_tcsicmp(TEXT("remove"),argv[1]+1)==0)

        {

            removeService();

        }

        else if(_tcsicmp(TEXT("debug"),argv[1]+1)==0)

        {

            bDebugServer=true;

            //debugService(argc,argv);

        }

        else

        {        //如果未能和上面的如何參數匹配,則可能是服務控制管理程式來啟動該程式。立即調用

            //StartServiceCtrlDispatcher 函數。

            printf("%s - install to install the service \n",SZAPPNAME);

            printf("%s - remove to remove the service \n",SZAPPNAME);

            printf("%s - debug to debug the service \n",SZAPPNAME);

            printf("\n StartServiceCtrlDispatcher being called.\n");

            printf("This may take several seconds.Please wait.\n");

            if(!StartServiceCtrlDispatcher(dispatchTable))

                AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));

            else

                AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));

        }

        exit(0);

    }

    return 0;

}

//服務進入點函數

void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv)    //具體服務的初始化入口函數
{
 printf("\n StartServiceCtrlDispatcher being called.\n");

}

void  WINAPI  Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)

{

    //註冊服務控制處理函數

    sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);

    //如果註冊失敗

    if(!sshStatusHandle)

    {

        goto cleanup;

        return;

    }

    //初始化 SERVICE_STATUS 結構中的成員

    ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;

    ssStatus.dwServiceSpecificExitCode=0;

    //更新服務狀態

    if(!ReportStatusToSCMgr(

        SERVICE_START_PENDING,//服務狀態,The service is starting.

        NO_ERROR,            //退出碼        

        3000))                   //等待時間

        goto cleanup;        //更新服務狀態失敗則轉向 cleanup

    ServiceStart(dwArgc,lpszArgv);

    return;

cleanup:

    //把服務狀態更新為 SERVICE_STOPPED,並退出。

    if(sshStatusHandle)

        (void)ReportStatusToSCMgr(SERVICE_STOPPED,dwErr,0);

}

//控制處理常式函數

void WINAPI Service_Ctrl(DWORD dwCtrlCode)

{

    //處理控制請求碼

    switch(dwCtrlCode)

    {

        // 先更新服務狀態為 SERVICDE_STOP_PENDING,再停止服務。

    case SERVICE_CONTROL_STOP:

        ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

        //ServiceStop();     //由具體的服務程式實現

        return;

        // 暫停服務

    case SERVICE_CONTROL_PAUSE:

        ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

        //ServicePause();    //由具體的服務程式實現

        ssStatus.dwCurrentState=SERVICE_PAUSED;

        return;

        // 繼續服務

    case SERVICE_CONTROL_CONTINUE:

        ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);

        //ServiceContinue(); //由具體的服務程式實現

        ssStatus.dwCurrentState=SERVICE_RUNNING;

        return;

        // 更新服務狀態

    case SERVICE_CONTROL_INTERROGATE:

        break;

        // 無效控制碼

    default:

        break;

    }

    ReportStatusToSCMgr(ssStatus.dwCurrentState,NO_ERROR,0);

}

//安裝服務程式

void installService()

{

    SC_HANDLE schService;

    SC_HANDLE schSCManager;

    TCHAR szPath[512];

    //得到程式磁碟檔案的路徑

    if(GetModuleFileName(NULL,szPath,512)==0)

    {

        _tprintf(TEXT("Unable to install %s - %s \n"),

            TEXT(SZAPPNAME),

            GetLastError());//@1擷取調用函數返回的最後錯誤碼

        return;

    }

    //開啟服務管理資料庫

    schSCManager=OpenSCManager(

        NULL,    //本機電腦

        NULL,    //預設的資料庫

        SC_MANAGER_ALL_ACCESS  //要求所有的訪問權

        );

    if(schSCManager)

    {

        // 登記服務程式

        schService = CreateService(

            schSCManager,                    //服務管理資料庫控制代碼

            TEXT(SZSERVICENAME),             //服務名

            TEXT(SZAPPNAME),       //用於顯示服務的標識

            SERVICE_ALL_ACCESS,              //響應所有的訪問請求

            SERVICE_WIN32_OWN_PROCESS,       //服務類型

            //SERVICE_DEMAND_START,            //啟動類型
            SERVICE_AUTO_START,

            SERVICE_ERROR_NORMAL,            //錯誤控制類型

            szPath,                              //服務程式磁碟檔案的路徑

            NULL,                                //服務不屬於任何組

            NULL,                                //沒有tag標識符

            NULL,              //啟動服務所依賴的服務或服務組,這裡僅僅是一個Null 字元串

            NULL,                                //LocalSystem 帳號

            NULL);

        if(schService)

        {

            _tprintf(TEXT("%s installed. \n"),TEXT(SZAPPNAME));

            CloseServiceHandle(schService);

        }

        else

        {

            _tprintf(TEXT("CreateService failed - %s \n"),GetLastError());

        }

        CloseServiceHandle(schSCManager);

    }

    else

        _tprintf(TEXT("OpenSCManager failed - %s \n"),GetLastError());

}

void removeService()
{
    SC_HANDLE service, scm;             //定義服務控制代碼和服務控制管理資料庫控制代碼
    SERVICE_STATUS status;                //定義服務狀態結構
    //if (argc != 2)  return;             //如果命令列參數的個數小於2,則不執行卸載程式
    // 開啟服務控制管理資料庫,並返回服務控制管理資料庫的控制代碼
    scm = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
    // 獲得服務控制代碼,並添加服務訪問中的刪除選項
    //service = OpenService(scm, argv[1],SERVICE_ALL_ACCESS | DELETE);
    service = OpenService(scm, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS | DELETE);
    // 獲得服務的目前狀態
    QueryServiceStatus(service, &status);
    // 如果服務不處於停止狀態,則將其狀態設定為停止狀態
    if (status.dwCurrentState != SERVICE_STOPPED)
        ControlService(service,SERVICE_CONTROL_STOP, &status);
    DeleteService(service);                // 刪除服務
    CloseServiceHandle(service);        // 關閉新服務控制代碼
    CloseServiceHandle(scm);            // 關閉服務控制管理資料庫控制代碼

}

void debugService(int argc,char** argv)
{

}

bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint)
{
   return true;
}

void AddToMessageLog(LPTSTR lpszMsg)
{
 

 

}

 

http://blog.chinaunix.net/u1/37538/showart_493320.html

http://www.wei2008.com/Code/softdown.asp?softid=35719 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.