// 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