#pragma once
#ifdef WIN32
#include
#include
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "strsafe.lib")
#define SVCNAME TEXT("wind.cosmos.dbsync.server")
#define SVCDISPLAYNAME TEXT("wind.cosmos.dbsync.server")
#define SVC_ERROR ((DWORD)0xC0020001L)
SERVICE_STATUS gSvcStatus;
SERVICE_STATUS_HANDLE gSvcStatusHandle;
HANDLE ghSvcStopEvent = NULL;
typedef VOID(*REAL_FUNCTION)(DWORD dwArgc, LPTSTR *lpszArgv);
static VOID SvcInit(DWORD dwArgc, LPTSTR *lpszArgv);
static VOID ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
static VOID WINAPI SvcCtrlHandler(DWORD dwCtrl);
static VOID SvcReportEvent(LPTSTR szFunction);
REAL_FUNCTION _realFunc = NULL;
void Print(const char* log)
{
static ofstream out("D:\\test.txt");
out << log << endl;
}
void serviceInstall() {
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR szPath[MAX_PATH];
if (!GetModuleFileName(NULL, szPath, MAX_PATH))
{
printf("Cannot install service (%d)\n", GetLastError());
return;
}
schSCManager = OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS);
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return;
}
schService = CreateService(
schSCManager,
SVCNAME,
SVCDISPLAYNAME,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
szPath,
NULL,
NULL,
NULL,
NULL,
NULL);
if (schService == NULL)
{
CloseServiceHandle(schSCManager);
wchar_t errInfo[256];
_snwprintf(errInfo, 256, (const wchar_t*)"Windows服务安装失败(%d)\n", GetLastError());
MessageBox(NULL, errInfo, TEXT("失败"), MB_ICONERROR | MB_OK);
return;
}
else {
SERVICE_DESCRIPTION service_desc;
service_desc.lpDescription = TEXT("Cosmos数据库同步服务端.");
ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &service_desc);
SERVICE_FAILURE_ACTIONS failure_actions;
failure_actions.dwResetPeriod = 60 * 60;
failure_actions.lpRebootMsg = TEXT("wind.cosmos.dbsync.server服务发生过异常崩溃");
failure_actions.lpCommand = NULL;
failure_actions.cActions = 3;
SC_ACTION* actions = new SC_ACTION[3];
actions[0].Type = SC_ACTION_RESTART;
actions[0].Delay = 1000 * 3;
actions[1].Type = SC_ACTION_RESTART;
actions[1].Delay = 1000 * 3;
actions[2].Type = SC_ACTION_RESTART;
actions[2].Delay = 1000 * 3;
failure_actions.lpsaActions = actions;
ChangeServiceConfig2(schService, SERVICE_CONFIG_FAILURE_ACTIONS, &failure_actions);
delete[] actions;
BOOL ret = StartService(schService, 0, NULL);
if (!ret)
{
DWORD err = GetLastError();
char chErr[64];
sprintf(chErr, "GetLastError = %d", err);
Print("StartService failed");
Print(chErr);
}
else
{
Print("StartService Success");
}
MessageBox(NULL,TEXT("服务(wind.cosmos.dbsync.server)安装成功"),TEXT("Succ"),MB_OK);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
}
void serviceUninstall() {
SC_HANDLE schSCManager;
SC_HANDLE schService;
TCHAR szPath[MAX_PATH];
if (!GetModuleFileName(NULL, szPath, MAX_PATH))
{
printf("Cannot install service (%d)\n", GetLastError());
return;
}
schSCManager = OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS);
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return;
}
schService = OpenService(schSCManager, SVCNAME, SC_MANAGER_ALL_ACCESS);
if (schService == NULL) {
CloseServiceHandle(schSCManager);
wchar_t errInfo[256];
_snwprintf(errInfo, 256, (const wchar_t*)"打开Windows服务(wind.cosmos.dbsync.server)失败.(%d)\n", GetLastError());
MessageBox(NULL, errInfo, TEXT("失败"), MB_ICONERROR | MB_OK);
return;
}
else {
if (DeleteService(schService)) {
MessageBox(NULL, TEXT("服务(wind.cosmos.dbsync.server)卸载成功"), TEXT("Succ"), MB_OK);
}
else {
wchar_t errInfo[256];
_snwprintf(errInfo, 256, (const wchar_t*)"卸载Windows服务(wind.cosmos.dbsync.server)失败.(%d)\n", GetLastError());
MessageBox(NULL, errInfo, TEXT("失败"), MB_ICONERROR | MB_OK);
}
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
}
}
VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
gSvcStatusHandle = RegisterServiceCtrlHandler(
SVCNAME,
SvcCtrlHandler);
if (!gSvcStatusHandle)
{
SvcReportEvent(TEXT("RegisterServiceCtrlHandler"));
return;
}
gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gSvcStatus.dwServiceSpecificExitCode = 0;
ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
SvcInit(dwArgc, lpszArgv);
}
static VOID SvcInit(DWORD dwArgc, LPTSTR *lpszArgv)
{
ghSvcStopEvent = CreateEvent(
NULL,
TRUE,
FALSE,
NULL);
if (ghSvcStopEvent == NULL)
{
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
return;
}
if (_realFunc != NULL) {
_realFunc(dwArgc, lpszArgv);
}
ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
while (1)
{
WaitForSingleObject(ghSvcStopEvent, INFINITE);
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
return;
}
}
static VOID ReportSvcStatus(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
gSvcStatus.dwCurrentState = dwCurrentState;
gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
gSvcStatus.dwWaitHint = dwWaitHint;
if (dwCurrentState == SERVICE_START_PENDING)
gSvcStatus.dwControlsAccepted = 0;
else gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
if ((dwCurrentState == SERVICE_RUNNING) ||
(dwCurrentState == SERVICE_STOPPED))
gSvcStatus.dwCheckPoint = 0;
else gSvcStatus.dwCheckPoint = dwCheckPoint++;
SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
}
static VOID WINAPI SvcCtrlHandler(DWORD dwCtrl)
{
switch (dwCtrl)
{
case SERVICE_CONTROL_STOP:
ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
SetEvent(ghSvcStopEvent);
ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);
return;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
}
static VOID SvcReportEvent(LPTSTR szFunction)
{
HANDLE hEventSource;
LPCTSTR lpszStrings[2];
TCHAR Buffer[80];
hEventSource = RegisterEventSource(NULL, SVCNAME);
if (NULL != hEventSource)
{
StringCchPrintf(Buffer, 80, TEXT("%s failed with %d"), szFunction, GetLastError());
lpszStrings[0] = SVCNAME;
lpszStrings[1] = Buffer;
ReportEvent(hEventSource,
EVENTLOG_ERROR_TYPE,
0,
SVC_ERROR,
NULL,
2,
0,
lpszStrings,
NULL);
DeregisterEventSource(hEventSource);
}
}
#endif
void runService();
VOID service_start_func(DWORD dwArgc, LPTSTR *lpszArgv)
{
Print("service_start_func");
runService();
}
bool runAsService(int argc, char** argv) {
Print("runAsService");
_realFunc = service_start_func;
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ SVCNAME, (LPSERVICE_MAIN_FUNCTION)SvcMain },
{ NULL, NULL }
};
if (!StartServiceCtrlDispatcher(DispatchTable))
{
MessageBox(NULL, TEXT("Windows服务.\n 命令行运行请带debug参数\n 安装服务请带install参数\n 卸载服务请带uninstall参数"), TEXT("警告"), MB_OK);
return false;
}
else {
return true;
}
}
int main(int argc, char** argv)
{
{
int runningMode = 0;
if (argc == 1)
{
runningMode = 4;
}
else
{
if (_stricmp(argv[1], "install") == 0) {
runningMode = 1;
}
else if (_stricmp(argv[1], "uninstall") == 0) {
runningMode = 2;
}
else if (_stricmp(argv[1], "debug") == 0) {
runningMode = 3;
}
}
switch (runningMode) {
case 1:
{
serviceInstall();
return 0;
}
case 2:
{
serviceUninstall();
return 0;
}
case 3:
{
break;
}
case 4:
runAsService(argc, argv);
return 0;
default:
return -1;
}
}
return 0;
}