// server.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 installService();
void removeService();
void debugService(int argc,char** argv);
bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint);
void AddToMessageLog(LPTSTR lpszMsg);
void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv);
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]==L"/")))
// {
// if(_stricmp(L"install",argv[1]+1)==0)
// {
// installService();
// }
// else if(_stricmp(L"remove",argv[1]+1)==0)
// {
// removeService();
// }
// else if(_stricmp(L"debug",argv[1]+1)==0)
// {
// bDebugServer=true;
// debugService(argc,argv);
// }
// else
// { installService();
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 WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)
{
sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);
if(!sshStatusHandle)
{
goto cleanup;
return;
}
ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode=0;
if(!ReportStatusToSCMgr(
SERVICE_START_PENDING,
NO_ERROR,
3000))
goto cleanup;
ServiceStart(dwArgc,lpszArgv);
return;
cleanup:
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_ERROR_NORMAL, //錯誤控制類型
szPath, //服務程序磁盤文件的路徑
NULL, //服務不屬於任何組
NULL, //沒有tag標識符
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 schService;
SC_HANDLE schSCManager;
//打開服務管理數據庫
schSCManager=OpenSCManager(
NULL, //本地計算機
NULL, //默認的數據庫
SC_MANAGER_ALL_ACCESS //要求所有的訪問權
);
if(schSCManager)
{
//獲取服務程序句柄
schService=OpenService(
schSCManager, //服務管理數據庫句柄
TEXT(SZSERVICENAME), //服務名
SERVICE_ALL_ACCESS //響應所有的訪問請求
);
if(schService)
{
//試圖停止服務
if(ControlService(
schService, //服務程序句柄
SERVICE_CONTROL_STOP, //停止服務請求碼
&ssStatus //接收最後的服務狀態信息
))
{
_tprintf(TEXT("Stopping %s."),TEXT(SZAPPNAME));
Sleep(1000);
//等待服務停止
//
while(QueryServiceStatus(schService,&ssStatus))
{
if(SERVICE_STOP_PENDING==ssStatus.dwCurrentState)
{
_tprintf(TEXT("."));
Sleep(1000);
}
else
break;
}
if(SERVICE_STOPPED==ssStatus.dwCurrentState)
_tprintf(TEXT("\n %s stopped. \n"),TEXT(SZAPPNAME));
else
_tprintf(TEXT("\n %s failed to stopp. \n"),TEXT(SZAPPNAME));
}
//刪除已安裝的服務程序安裝
if(DeleteService(schService))
_tprintf(TEXT("%s removed. \n"),TEXT(SZAPPNAME));
else
_tprintf(TEXT("DeleteService failed - %s. \n"), GetLastError());
CloseServiceHandle(schService);
}
else
_tprintf(TEXT("OpenService failed - %s \n"),GetLastError());
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s \n"),GetLastError());
}