25#if !defined(WINADVAPI)
26#if !defined(_ADVAPI32_)
27#define WINADVAPI DECLSPEC_IMPORT
33extern int main(
int argc,
char ** argv);
40SERVICE_STATUS serviceStatus;
42SERVICE_STATUS_HANDLE serviceStatusHandle =
nullptr;
44typedef WINADVAPI BOOL (WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);
46bool WinServiceInstall()
48 SC_HANDLE serviceControlManager = OpenSCManager(
nullptr,
nullptr, SC_MANAGER_CREATE_SERVICE);
50 if (serviceControlManager)
52 char path[_MAX_PATH + 10];
53 if (GetModuleFileName(
nullptr, path,
sizeof(path)/
sizeof(path[0]) ) > 0)
56 std::strcat(path,
" --service run");
57 service = CreateService(serviceControlManager,
62 SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
73 HMODULE advapi32 = GetModuleHandle(
"ADVAPI32.DLL");
76 CloseServiceHandle(service);
77 CloseServiceHandle(serviceControlManager);
81 CSD_T ChangeService_Config2 = (CSD_T) GetProcAddress(advapi32,
"ChangeServiceConfig2A");
82 if (!ChangeService_Config2)
84 CloseServiceHandle(service);
85 CloseServiceHandle(serviceControlManager);
89 SERVICE_DESCRIPTION sdBuf;
91 ChangeService_Config2(
93 SERVICE_CONFIG_DESCRIPTION,
97 _action[0].Type = SC_ACTION_RESTART;
98 _action[0].Delay = 10000;
99 SERVICE_FAILURE_ACTIONS sfa;
100 ZeroMemory(&sfa,
sizeof(SERVICE_FAILURE_ACTIONS));
101 sfa.lpsaActions = _action;
103 sfa.dwResetPeriod =INFINITE;
104 ChangeService_Config2(
106 SERVICE_CONFIG_FAILURE_ACTIONS,
109 CloseServiceHandle(service);
113 CloseServiceHandle(serviceControlManager);
116 printf(
"Service installed\n");
120bool WinServiceUninstall()
122 SC_HANDLE serviceControlManager = OpenSCManager(
nullptr,
nullptr, SC_MANAGER_CONNECT);
124 if (serviceControlManager)
126 SC_HANDLE service = OpenService(serviceControlManager,
130 SERVICE_STATUS serviceStatus2;
131 if (QueryServiceStatus(service, &serviceStatus2))
133 if (serviceStatus2.dwCurrentState == SERVICE_STOPPED)
134 DeleteService(service);
136 CloseServiceHandle(service);
139 CloseServiceHandle(serviceControlManager);
142 printf(
"Service uninstalled\n");
146void WINAPI ServiceControlHandler(DWORD controlCode)
150 case SERVICE_CONTROL_INTERROGATE:
153 case SERVICE_CONTROL_SHUTDOWN:
154 case SERVICE_CONTROL_STOP:
155 serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
156 SetServiceStatus(serviceStatusHandle, &serviceStatus);
161 case SERVICE_CONTROL_PAUSE:
163 serviceStatus.dwCurrentState = SERVICE_PAUSED;
164 SetServiceStatus(serviceStatusHandle, &serviceStatus);
167 case SERVICE_CONTROL_CONTINUE:
168 serviceStatus.dwCurrentState = SERVICE_RUNNING;
169 SetServiceStatus(serviceStatusHandle, &serviceStatus);
174 if ( controlCode >= 128 && controlCode <= 255 )
182 SetServiceStatus(serviceStatusHandle, &serviceStatus);
185void WINAPI ServiceMain(DWORD argc,
char *argv[])
188 serviceStatus.dwServiceType = SERVICE_WIN32;
189 serviceStatus.dwCurrentState = SERVICE_START_PENDING;
190 serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
191 serviceStatus.dwWin32ExitCode = NO_ERROR;
192 serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
193 serviceStatus.dwCheckPoint = 0;
194 serviceStatus.dwWaitHint = 0;
196 serviceStatusHandle = RegisterServiceCtrlHandler(
serviceName, ServiceControlHandler);
198 if ( serviceStatusHandle )
200 char path[_MAX_PATH + 1];
201 unsigned int i, last_slash = 0;
203 GetModuleFileName(
nullptr, path,
sizeof(path)/
sizeof(path[0]));
205 size_t pathLen = std::strlen(path);
206 for (i = 0; i < pathLen; i++)
208 if (path[i] ==
'\\') last_slash = i;
211 path[last_slash] = 0;
214 serviceStatus.dwCurrentState = SERVICE_START_PENDING;
215 SetServiceStatus(serviceStatusHandle, &serviceStatus);
218 SetCurrentDirectory(path);
221 serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
222 serviceStatus.dwCurrentState = SERVICE_RUNNING;
223 SetServiceStatus( serviceStatusHandle, &serviceStatus );
234 serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
235 SetServiceStatus(serviceStatusHandle, &serviceStatus);
240 serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
241 serviceStatus.dwCurrentState = SERVICE_STOPPED;
242 SetServiceStatus(serviceStatusHandle, &serviceStatus);
248 SERVICE_TABLE_ENTRY serviceTable[] =
254 if (!StartServiceCtrlDispatcher(serviceTable))
256 TC_LOG_ERROR(
"server.worldserver",
"StartService Failed. Error [{}]",
uint32(::GetLastError()));
#define TC_LOG_ERROR(filterType__,...)
char serviceDescription[]
int main(int argc, char **argv)