Windows Service Support
This commit is contained in:
parent
3aff761db6
commit
a78794c2e7
8 changed files with 191 additions and 339 deletions
|
@ -1,13 +1,13 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
# if (WIN32)
|
||||
# FILE(GLOB WIN_SRC win32/*.cpp)
|
||||
# include_directories(win32)
|
||||
# ADD_EXECUTABLE(spectrum2 ${SRC} ${WIN_SRC})
|
||||
# else()
|
||||
if (WIN32)
|
||||
FILE(GLOB WIN_SRC win32/*.cpp)
|
||||
include_directories(win32)
|
||||
ADD_EXECUTABLE(spectrum2 ${SRC} ${WIN_SRC})
|
||||
else()
|
||||
ADD_EXECUTABLE(spectrum2 ${SRC})
|
||||
# endif()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#else
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
// #include "win32/SpectrumService.h"
|
||||
#include "win32/ServiceWrapper.h"
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
@ -45,6 +45,13 @@ DEFINE_LOGGER(logger, "Spectrum");
|
|||
Swift::SimpleEventLoop *eventLoop_ = NULL;
|
||||
Component *component_ = NULL;
|
||||
UserManager *userManager_ = NULL;
|
||||
Config *config_ = NULL;
|
||||
|
||||
void stop() {
|
||||
userManager_->removeAllUsers(false);
|
||||
component_->stop();
|
||||
eventLoop_->stop();
|
||||
}
|
||||
|
||||
static void stop_spectrum() {
|
||||
userManager_->removeAllUsers(false);
|
||||
|
@ -125,7 +132,7 @@ static void daemonize(const char *cwd, const char *lock_file) {
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
Config config(argc, argv);
|
||||
|
||||
config_ = &config;
|
||||
boost::program_options::variables_map vm;
|
||||
bool no_daemon = false;
|
||||
std::string config_file;
|
||||
|
@ -160,9 +167,9 @@ int main(int argc, char **argv)
|
|||
("version,v", "Shows Spectrum version")
|
||||
;
|
||||
#ifdef WIN32
|
||||
// desc.add_options()
|
||||
// ("install-service,i", "Install spectrum as Windows service")
|
||||
// ("uninstall-service,u", "Uninstall Windows service");
|
||||
desc.add_options()
|
||||
("install-service,i", "Install spectrum as Windows service")
|
||||
("uninstall-service,u", "Uninstall Windows service");
|
||||
#endif
|
||||
try
|
||||
{
|
||||
|
@ -192,18 +199,17 @@ int main(int argc, char **argv)
|
|||
no_daemon = true;
|
||||
}
|
||||
#ifdef WIN32
|
||||
#if 0
|
||||
if (vm.count("install-service")) {
|
||||
SpectrumService ntservice;
|
||||
ServiceWrapper ntservice("Spectrum2");
|
||||
if (!ntservice.IsInstalled()) {
|
||||
// determine the name of the currently executing file
|
||||
char szFilePath[MAX_PATH];
|
||||
GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
|
||||
GetModuleFileNameA(NULL, szFilePath, sizeof(szFilePath));
|
||||
std::string exe_file(szFilePath);
|
||||
std::string config_file = exe_file.replace(exe_file.end() - 4, exe_file.end(), ".cfg");
|
||||
std::string service_path = std::string(szFilePath) + std::string(" --config ") + config_file;
|
||||
|
||||
if (ntservice.Install(service_path.c_str())) {
|
||||
if (ntservice.Install((char *)service_path.c_str())) {
|
||||
std::cout << "Successfully installed" << std::endl;
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -216,9 +222,9 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
if (vm.count("uninstall-service")) {
|
||||
SpectrumService ntservice;
|
||||
ServiceWrapper ntservice("Spectrum2");
|
||||
if (ntservice.IsInstalled()) {
|
||||
if (ntservice.Remove()) {
|
||||
if (ntservice.UnInstall()) {
|
||||
std::cout << "Successfully removed" << std::endl;
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -229,8 +235,7 @@ int main(int argc, char **argv)
|
|||
std::cout << "Service not installed" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
|
@ -310,36 +315,49 @@ int main(int argc, char **argv)
|
|||
// removeOldIcons(CONFIG_STRING(&config, "service.working_dir") + "/icons");
|
||||
}
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
ServiceWrapper ntservice("Spectrum2");
|
||||
if (ntservice.IsInstalled()) {
|
||||
ntservice.RunService();
|
||||
} else {
|
||||
mainloop();
|
||||
}
|
||||
#else
|
||||
mainloop();
|
||||
#endif
|
||||
}
|
||||
|
||||
Logging::initMainLogging(&config);
|
||||
int mainloop() {
|
||||
|
||||
Logging::initMainLogging(config_);
|
||||
|
||||
#ifndef WIN32
|
||||
if (!CONFIG_STRING(&config, "service.group").empty() ||!CONFIG_STRING(&config, "service.user").empty() ) {
|
||||
if (!CONFIG_STRING(config_, "service.group").empty() ||!CONFIG_STRING(config_, "service.user").empty() ) {
|
||||
struct rlimit limit;
|
||||
getrlimit(RLIMIT_CORE, &limit);
|
||||
|
||||
if (!CONFIG_STRING(&config, "service.group").empty()) {
|
||||
if (!CONFIG_STRING(config_, "service.group").empty()) {
|
||||
struct group *gr;
|
||||
if ((gr = getgrnam(CONFIG_STRING(&config, "service.group").c_str())) == NULL) {
|
||||
std::cerr << "Invalid service.group name " << CONFIG_STRING(&config, "service.group") << "\n";
|
||||
if ((gr = getgrnam(CONFIG_STRING(config_, "service.group").c_str())) == NULL) {
|
||||
std::cerr << "Invalid service.group name " << CONFIG_STRING(config_, "service.group") << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (((setgid(gr->gr_gid)) != 0) || (initgroups(CONFIG_STRING(&config, "service.user").c_str(), gr->gr_gid) != 0)) {
|
||||
std::cerr << "Failed to set service.group name " << CONFIG_STRING(&config, "service.group") << " - " << gr->gr_gid << ":" << strerror(errno) << "\n";
|
||||
if (((setgid(gr->gr_gid)) != 0) || (initgroups(CONFIG_STRING(config_, "service.user").c_str(), gr->gr_gid) != 0)) {
|
||||
std::cerr << "Failed to set service.group name " << CONFIG_STRING(config_, "service.group") << " - " << gr->gr_gid << ":" << strerror(errno) << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CONFIG_STRING(&config, "service.user").empty()) {
|
||||
if (!CONFIG_STRING(config_, "service.user").empty()) {
|
||||
struct passwd *pw;
|
||||
if ((pw = getpwnam(CONFIG_STRING(&config, "service.user").c_str())) == NULL) {
|
||||
std::cerr << "Invalid service.user name " << CONFIG_STRING(&config, "service.user") << "\n";
|
||||
if ((pw = getpwnam(CONFIG_STRING(config_, "service.user").c_str())) == NULL) {
|
||||
std::cerr << "Invalid service.user name " << CONFIG_STRING(config_, "service.user") << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((setuid(pw->pw_uid)) != 0) {
|
||||
std::cerr << "Failed to set service.user name " << CONFIG_STRING(&config, "service.user") << " - " << pw->pw_uid << ":" << strerror(errno) << "\n";
|
||||
std::cerr << "Failed to set service.user name " << CONFIG_STRING(config_, "service.user") << " - " << pw->pw_uid << ":" << strerror(errno) << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -355,14 +373,14 @@ int main(int argc, char **argv)
|
|||
Swift::SimpleEventLoop eventLoop;
|
||||
|
||||
Swift::BoostNetworkFactories *factories = new Swift::BoostNetworkFactories(&eventLoop);
|
||||
UserRegistry userRegistry(&config, factories);
|
||||
UserRegistry userRegistry(config_, factories);
|
||||
|
||||
Component transport(&eventLoop, factories, &config, NULL, &userRegistry);
|
||||
Component transport(&eventLoop, factories, config_, NULL, &userRegistry);
|
||||
component_ = &transport;
|
||||
// Logger logger(&transport);
|
||||
|
||||
std::string error;
|
||||
StorageBackend *storageBackend = StorageBackend::createBackend(&config, error);
|
||||
StorageBackend *storageBackend = StorageBackend::createBackend(config_, error);
|
||||
if (storageBackend == NULL) {
|
||||
if (!error.empty()) {
|
||||
std::cerr << error << "\n";
|
||||
|
@ -393,7 +411,7 @@ int main(int argc, char **argv)
|
|||
|
||||
FileTransferManager ftManager(&transport, &userManager);
|
||||
|
||||
NetworkPluginServer plugin(&transport, &config, &userManager, &ftManager, &discoItemsResponder);
|
||||
NetworkPluginServer plugin(&transport, config_, &userManager, &ftManager, &discoItemsResponder);
|
||||
plugin.start();
|
||||
|
||||
AdminInterface adminInterface(&transport, &userManager, &plugin, storageBackend, userRegistration);
|
||||
|
|
120
spectrum/src/win32/ServiceWrapper.cpp
Normal file
120
spectrum/src/win32/ServiceWrapper.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
#include "ServiceWrapper.h"
|
||||
|
||||
|
||||
LPSTR ServiceName;
|
||||
SERVICE_STATUS ServiceStatus;
|
||||
SERVICE_STATUS_HANDLE ServiceStatusHandle;
|
||||
|
||||
bool doAction (int action, int desiredAccess, LPSTR path = NULL);
|
||||
|
||||
enum actions {
|
||||
DO_INSTALL, DO_DELETE, DO_CHECK
|
||||
};
|
||||
|
||||
|
||||
ServiceWrapper::ServiceWrapper(LPSTR serviceName)
|
||||
{
|
||||
ServiceName = serviceName;
|
||||
ServiceStatusHandle = 0;
|
||||
}
|
||||
|
||||
ServiceWrapper::~ServiceWrapper(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool ServiceWrapper::Install(LPSTR commandLine) {
|
||||
return doAction(DO_INSTALL, SC_MANAGER_ALL_ACCESS, commandLine);
|
||||
}
|
||||
|
||||
bool ServiceWrapper::UnInstall() {
|
||||
return doAction(DO_DELETE, SC_MANAGER_ALL_ACCESS);
|
||||
}
|
||||
|
||||
bool ServiceWrapper::IsInstalled() {
|
||||
return doAction(DO_CHECK, SC_MANAGER_CONNECT);
|
||||
}
|
||||
|
||||
bool doAction(int action, int desiredAccess, LPSTR path) {
|
||||
SC_HANDLE scm = OpenSCManager(NULL, NULL, desiredAccess);
|
||||
SC_HANDLE service = NULL;
|
||||
if (!scm) return FALSE;
|
||||
|
||||
switch(action) {
|
||||
case DO_INSTALL:
|
||||
service = CreateServiceA(
|
||||
scm,
|
||||
ServiceName,
|
||||
ServiceName,
|
||||
SERVICE_ALL_ACCESS,
|
||||
SERVICE_WIN32_OWN_PROCESS,
|
||||
SERVICE_DEMAND_START,
|
||||
SERVICE_ERROR_NORMAL,
|
||||
path,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
return (service != NULL);
|
||||
break;
|
||||
case DO_DELETE:
|
||||
service = OpenServiceA(scm, ServiceName, DELETE);
|
||||
if (service == NULL)
|
||||
return FALSE;
|
||||
if (DeleteService(service))
|
||||
return TRUE;
|
||||
break;
|
||||
case DO_CHECK:
|
||||
service = OpenServiceA(scm, ServiceName, SERVICE_QUERY_STATUS);
|
||||
return (service != NULL);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
CloseServiceHandle(service);
|
||||
CloseServiceHandle(scm);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void WINAPI ServiceControlHandler(DWORD controlCode) {
|
||||
switch (controlCode) {
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
break;
|
||||
case SERVICE_CONTROL_STOP:
|
||||
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
stop();
|
||||
}
|
||||
|
||||
void WINAPI ServiceMain(DWORD argc, LPSTR *argv) {
|
||||
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||
ServiceStatus.dwServiceSpecificExitCode = NO_ERROR;
|
||||
|
||||
ServiceStatusHandle = RegisterServiceCtrlHandlerA(ServiceName, ServiceControlHandler);
|
||||
if (ServiceStatusHandle) {
|
||||
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
ServiceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
|
||||
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
mainloop();
|
||||
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
ServiceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
|
||||
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
||||
SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceWrapper::RunService() {
|
||||
SERVICE_TABLE_ENTRYA serviceTable[] = {
|
||||
{ ServiceName, ServiceMain },
|
||||
{ NULL, NULL}
|
||||
};
|
||||
|
||||
StartServiceCtrlDispatcherA(serviceTable);
|
||||
}
|
19
spectrum/src/win32/ServiceWrapper.h
Normal file
19
spectrum/src/win32/ServiceWrapper.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include "transport/config.h"
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
class ServiceWrapper
|
||||
{
|
||||
public:
|
||||
ServiceWrapper(LPSTR serviceName);
|
||||
~ServiceWrapper(void);
|
||||
bool Install(LPSTR commandLine);
|
||||
bool UnInstall();
|
||||
bool IsInstalled();
|
||||
void RunService();
|
||||
};
|
||||
|
||||
int mainloop();
|
||||
void stop();
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#include "SpectrumService.h"
|
||||
|
||||
SpectrumService::SpectrumService(void) {
|
||||
serviceName = "Spectrum2";
|
||||
displayName = "Spectrum2 XMPP Transport";
|
||||
username = NULL;
|
||||
password = NULL;
|
||||
}
|
||||
|
||||
SpectrumService::~SpectrumService(void) {}
|
||||
|
||||
void SpectrumService::Stop() {
|
||||
ReportStatus((DWORD)SERVICE_STOP_PENDING);
|
||||
}
|
||||
|
||||
void SpectrumService::Run(DWORD argc, LPTSTR *argv) {
|
||||
ReportStatus((DWORD)SERVICE_RUNNING);
|
||||
main(argc, argv);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
#include <windows.h>
|
||||
#include "WindowsService.h"
|
||||
|
||||
class SpectrumService : public WindowsService {
|
||||
|
||||
public:
|
||||
SpectrumService(void);
|
||||
~SpectrumService(void);
|
||||
protected:
|
||||
void Stop();
|
||||
void Run(DWORD argc, LPTSTR *argv);
|
||||
};
|
||||
|
||||
int main(int argc, char **argv);
|
|
@ -1,214 +0,0 @@
|
|||
/* Copyright (C) 2005 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#include <windows.h>
|
||||
#include <assert.h>
|
||||
#include ".\windowsservice.h"
|
||||
|
||||
static WindowsService *gService;
|
||||
|
||||
WindowsService::WindowsService(void) :
|
||||
statusCheckpoint(0),
|
||||
serviceName(NULL),
|
||||
inited(false),
|
||||
dwAcceptedControls(SERVICE_ACCEPT_STOP),
|
||||
debugging(false)
|
||||
{
|
||||
gService= this;
|
||||
status.dwServiceType= SERVICE_WIN32_OWN_PROCESS;
|
||||
status.dwServiceSpecificExitCode= 0;
|
||||
}
|
||||
|
||||
WindowsService::~WindowsService(void)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL WindowsService::Install(const char *szFilePath)
|
||||
{
|
||||
bool ret_val= false;
|
||||
SC_HANDLE newService;
|
||||
SC_HANDLE scm;
|
||||
|
||||
if (IsInstalled()) return true;
|
||||
|
||||
// open a connection to the SCM
|
||||
if (!(scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
|
||||
return false;
|
||||
|
||||
newService= CreateService(scm, serviceName, displayName,
|
||||
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
|
||||
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
|
||||
szFilePath, NULL, NULL, NULL, username,
|
||||
password);
|
||||
|
||||
if (newService)
|
||||
{
|
||||
CloseServiceHandle(newService);
|
||||
ret_val= true;
|
||||
}
|
||||
|
||||
CloseServiceHandle(scm);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
BOOL WindowsService::Init()
|
||||
{
|
||||
assert(serviceName != NULL);
|
||||
|
||||
if (inited) return true;
|
||||
|
||||
SERVICE_TABLE_ENTRY stb[] =
|
||||
{
|
||||
{ (LPSTR)serviceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
inited= true;
|
||||
return StartServiceCtrlDispatcher(stb); //register with the Service Manager
|
||||
}
|
||||
|
||||
BOOL WindowsService::Remove()
|
||||
{
|
||||
bool ret_val= false;
|
||||
|
||||
if (! IsInstalled())
|
||||
return true;
|
||||
|
||||
// open a connection to the SCM
|
||||
SC_HANDLE scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE);
|
||||
if (! scm)
|
||||
return false;
|
||||
|
||||
SC_HANDLE service= OpenService(scm, serviceName, DELETE);
|
||||
if (service)
|
||||
{
|
||||
if (DeleteService(service))
|
||||
ret_val= true;
|
||||
DWORD dw= ::GetLastError();
|
||||
CloseServiceHandle(service);
|
||||
}
|
||||
|
||||
CloseServiceHandle(scm);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
BOOL WindowsService::IsInstalled()
|
||||
{
|
||||
BOOL ret_val= FALSE;
|
||||
|
||||
SC_HANDLE scm= ::OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
|
||||
SC_HANDLE serv_handle= ::OpenService(scm, serviceName, SERVICE_QUERY_STATUS);
|
||||
|
||||
ret_val= serv_handle != NULL;
|
||||
|
||||
::CloseServiceHandle(serv_handle);
|
||||
::CloseServiceHandle(scm);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void WindowsService::SetAcceptedControls(DWORD acceptedControls)
|
||||
{
|
||||
dwAcceptedControls= acceptedControls;
|
||||
}
|
||||
|
||||
|
||||
BOOL WindowsService::ReportStatus(DWORD currentState, DWORD waitHint,
|
||||
DWORD dwError)
|
||||
{
|
||||
if(debugging) return TRUE;
|
||||
|
||||
if(currentState == SERVICE_START_PENDING)
|
||||
status.dwControlsAccepted= 0;
|
||||
else
|
||||
status.dwControlsAccepted= dwAcceptedControls;
|
||||
|
||||
status.dwCurrentState= currentState;
|
||||
status.dwWin32ExitCode= dwError != 0 ?
|
||||
ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR;
|
||||
status.dwWaitHint= waitHint;
|
||||
status.dwServiceSpecificExitCode= dwError;
|
||||
|
||||
if(currentState == SERVICE_RUNNING || currentState == SERVICE_STOPPED)
|
||||
{
|
||||
status.dwCheckPoint= 0;
|
||||
statusCheckpoint= 0;
|
||||
}
|
||||
else
|
||||
status.dwCheckPoint= ++statusCheckpoint;
|
||||
|
||||
// Report the status of the service to the service control manager.
|
||||
BOOL result= SetServiceStatus(statusHandle, &status);
|
||||
if (!result)
|
||||
Log("ReportStatus failed");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void WindowsService::RegisterAndRun(DWORD argc, LPTSTR *argv)
|
||||
{
|
||||
statusHandle= ::RegisterServiceCtrlHandler(serviceName, ControlHandler);
|
||||
if (statusHandle && ReportStatus(SERVICE_START_PENDING))
|
||||
Run(argc, argv);
|
||||
ReportStatus(SERVICE_STOPPED);
|
||||
}
|
||||
|
||||
void WindowsService::HandleControlCode(DWORD opcode)
|
||||
{
|
||||
// Handle the requested control code.
|
||||
switch(opcode) {
|
||||
case SERVICE_CONTROL_STOP:
|
||||
// Stop the service.
|
||||
status.dwCurrentState= SERVICE_STOP_PENDING;
|
||||
Stop();
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_PAUSE:
|
||||
status.dwCurrentState= SERVICE_PAUSE_PENDING;
|
||||
Pause();
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_CONTINUE:
|
||||
status.dwCurrentState= SERVICE_CONTINUE_PENDING;
|
||||
Continue();
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_SHUTDOWN:
|
||||
Shutdown();
|
||||
break;
|
||||
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
ReportStatus(status.dwCurrentState);
|
||||
break;
|
||||
|
||||
default:
|
||||
// invalid control code
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WINAPI WindowsService::ServiceMain(DWORD argc, LPTSTR *argv)
|
||||
{
|
||||
assert(gService != NULL);
|
||||
|
||||
// register our service control handler:
|
||||
gService->RegisterAndRun(argc, argv);
|
||||
}
|
||||
|
||||
void WINAPI WindowsService::ControlHandler(DWORD opcode)
|
||||
{
|
||||
assert(gService != NULL);
|
||||
|
||||
return gService->HandleControlCode(opcode);
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/* Copyright (C) 2005 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||
|
||||
#pragma once
|
||||
|
||||
class WindowsService
|
||||
{
|
||||
protected:
|
||||
bool inited;
|
||||
const char *serviceName;
|
||||
const char *displayName;
|
||||
const char *username;
|
||||
const char *password;
|
||||
SERVICE_STATUS_HANDLE statusHandle;
|
||||
DWORD statusCheckpoint;
|
||||
SERVICE_STATUS status;
|
||||
DWORD dwAcceptedControls;
|
||||
bool debugging;
|
||||
|
||||
public:
|
||||
WindowsService(void);
|
||||
~WindowsService(void);
|
||||
|
||||
BOOL Install(const char *szFilePath);
|
||||
BOOL Remove();
|
||||
BOOL Init();
|
||||
BOOL IsInstalled();
|
||||
void SetAcceptedControls(DWORD acceptedControls);
|
||||
void Debug(bool debugFlag) { debugging= debugFlag; }
|
||||
|
||||
public:
|
||||
static void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
|
||||
static void WINAPI ControlHandler(DWORD CtrlType);
|
||||
|
||||
protected:
|
||||
virtual void Run(DWORD argc, LPTSTR *argv)= 0;
|
||||
virtual void Stop() {}
|
||||
virtual void Shutdown() {}
|
||||
virtual void Pause() {}
|
||||
virtual void Continue() {}
|
||||
virtual void Log(const char *msg) {}
|
||||
|
||||
BOOL ReportStatus(DWORD currentStatus, DWORD waitHint= 3000, DWORD dwError=0);
|
||||
void HandleControlCode(DWORD opcode);
|
||||
void RegisterAndRun(DWORD argc, LPTSTR *argv);
|
||||
};
|
Loading…
Add table
Reference in a new issue