WIP: adding windows service
This commit is contained in:
parent
465f942baf
commit
7271aa2cb0
56
src/main.cpp
56
src/main.cpp
|
@ -31,6 +31,7 @@
|
|||
#include "http/httpserver.hpp"
|
||||
#include "http/webapp.hpp"
|
||||
#include "tracker.hpp"
|
||||
#include "service.hpp"
|
||||
|
||||
UDPT::Logger *logger = NULL;
|
||||
|
||||
|
@ -83,6 +84,9 @@ int main(int argc, char *argv[])
|
|||
("config,c", boost::program_options::value<std::string>()->default_value("/etc/udpt.conf"), "configuration file to use")
|
||||
#ifdef linux
|
||||
("interactive,i", "doesn't start as daemon")
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
("service,s", boost::program_options::value<std::string>(), "start/stop/install/uninstall service")
|
||||
#endif
|
||||
;
|
||||
|
||||
|
@ -109,6 +113,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
#ifdef linux
|
||||
("daemon.chdir", boost::program_options::value<std::string>()->default_value("/"), "home directory for daemon")
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
("service.name", boost::program_options::value<std::string>()->default_value("udpt"), "service name to use")
|
||||
#endif
|
||||
;
|
||||
|
||||
|
@ -177,6 +184,55 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
::signal(SIGTERM, _signal_handler);
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
UDPT::Service svc(var_map);
|
||||
if (var_map.count("service"))
|
||||
{
|
||||
const std::string& action = var_map["service"].as<std::string>();
|
||||
try
|
||||
{
|
||||
if ("install" == action)
|
||||
{
|
||||
std::cout << "Installing service..." << std::endl;
|
||||
svc.install();
|
||||
std::cout << "Installed." << std::endl;
|
||||
}
|
||||
else if ("uninstall" == action)
|
||||
{
|
||||
std::cout << "Removing service..." << std::endl;
|
||||
svc.uninstall();
|
||||
std::cout << "Removed." << std::endl;
|
||||
}
|
||||
else if ("start" == action)
|
||||
{
|
||||
svc.start();
|
||||
}
|
||||
else if ("stop" == action)
|
||||
{
|
||||
svc.stop();
|
||||
}
|
||||
}
|
||||
catch (const UDPT::OSError& ex)
|
||||
{
|
||||
std::cout << "An operating system error occurred: " << ex.getErrorCode() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
svc.setup();
|
||||
}
|
||||
catch (const OSError& err)
|
||||
{
|
||||
if (ERROR_FAILED_SERVICE_CONTROLLER_CONNECT != err.getErrorCode())
|
||||
{
|
||||
logger->log(UDPT::Logger::LL_ERROR, "failed to start as service");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tracker.start(var_map);
|
||||
tracker.wait();
|
||||
|
|
135
src/service.cpp
Normal file
135
src/service.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright © 2012-2016 Naim A.
|
||||
*
|
||||
* This file is part of UDPT.
|
||||
*
|
||||
* UDPT 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* UDPT 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 UDPT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "service.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
namespace UDPT
|
||||
{
|
||||
Service::Service(const boost::program_options::variables_map& conf) : m_conf(conf)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Service::~Service()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Service::install()
|
||||
{
|
||||
std::string& binaryPath = getFilename();
|
||||
binaryPath = "\"" + binaryPath + "\"";
|
||||
std::shared_ptr<void> svcMgr = getServiceManager(SC_MANAGER_CREATE_SERVICE);
|
||||
{
|
||||
SC_HANDLE installedService = ::CreateService(reinterpret_cast<SC_HANDLE>(svcMgr.get()),
|
||||
m_conf["service.name"].as<std::string>().c_str(),
|
||||
"UDPT Tracker",
|
||||
SC_MANAGER_CREATE_SERVICE,
|
||||
SERVICE_WIN32_OWN_PROCESS,
|
||||
SERVICE_AUTO_START,
|
||||
SERVICE_ERROR_NORMAL,
|
||||
binaryPath.c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
if (nullptr == installedService)
|
||||
{
|
||||
throw OSError();
|
||||
}
|
||||
|
||||
::CloseServiceHandle(installedService);
|
||||
}
|
||||
}
|
||||
|
||||
void Service::uninstall()
|
||||
{
|
||||
std::shared_ptr<void> service = getService(DELETE);
|
||||
BOOL bRes = ::DeleteService(reinterpret_cast<SC_HANDLE>(service.get()));
|
||||
if (FALSE == bRes)
|
||||
{
|
||||
throw OSError();
|
||||
}
|
||||
}
|
||||
|
||||
void Service::start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Service::stop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Service::setup()
|
||||
{
|
||||
SERVICE_TABLE_ENTRY service = { 0 };
|
||||
service.lpServiceName = const_cast<char*>(m_conf["service.name"].as<std::string>().c_str());
|
||||
service.lpServiceProc = reinterpret_cast<LPSERVICE_MAIN_FUNCTION>(&Service::serviceMain);
|
||||
if (FALSE == ::StartServiceCtrlDispatcher(&service))
|
||||
{
|
||||
throw OSError();
|
||||
}
|
||||
}
|
||||
|
||||
VOID Service::serviceMain(DWORD argc, LPCSTR argv[])
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<void> Service::getService(DWORD access)
|
||||
{
|
||||
std::shared_ptr<void> serviceManager = getServiceManager(access);
|
||||
{
|
||||
SC_HANDLE service = ::OpenService(reinterpret_cast<SC_HANDLE>(serviceManager.get()), m_conf["service.name"].as<std::string>().c_str(), access);
|
||||
if (nullptr == service)
|
||||
{
|
||||
throw OSError();
|
||||
}
|
||||
return std::shared_ptr<void>(service, ::CloseServiceHandle);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<void> Service::getServiceManager(DWORD access)
|
||||
{
|
||||
SC_HANDLE svcMgr = ::OpenSCManager(NULL, NULL, access);
|
||||
if (nullptr == svcMgr)
|
||||
{
|
||||
throw OSError();
|
||||
}
|
||||
return std::shared_ptr<void>(svcMgr, ::CloseServiceHandle);
|
||||
}
|
||||
|
||||
std::string Service::getFilename()
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
DWORD dwRet = ::GetModuleFileName(NULL, filename, sizeof(filename) / sizeof(char));
|
||||
if (0 == dwRet)
|
||||
{
|
||||
throw OSError();
|
||||
}
|
||||
return std::string(filename);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
60
src/service.hpp
Normal file
60
src/service.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright © 2012-2016 Naim A.
|
||||
*
|
||||
* This file is part of UDPT.
|
||||
*
|
||||
* UDPT 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* UDPT 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 UDPT. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include "multiplatform.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
#ifdef WIN32
|
||||
namespace UDPT
|
||||
{
|
||||
class Service
|
||||
{
|
||||
public:
|
||||
Service(const boost::program_options::variables_map& conf);
|
||||
|
||||
virtual ~Service();
|
||||
|
||||
|
||||
void install();
|
||||
|
||||
void uninstall();
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
||||
void setup();
|
||||
private:
|
||||
const boost::program_options::variables_map& m_conf;
|
||||
|
||||
std::shared_ptr<void> getService(DWORD access);
|
||||
|
||||
static VOID WINAPI handler(DWORD controlCode);
|
||||
|
||||
static VOID WINAPI serviceMain(DWORD argc, LPCSTR argv[]);
|
||||
|
||||
static std::shared_ptr<void> getServiceManager(DWORD access);
|
||||
|
||||
static std::string getFilename();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -59,7 +59,7 @@
|
|||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>ws2_32.lib;sqlite3.lib;</AdditionalDependencies>
|
||||
<AdditionalDependencies>ws2_32.lib;sqlite3.lib;advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
@ -73,10 +73,11 @@
|
|||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>ws2_32.lib;sqlite3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<EnableCOMDATFolding>
|
||||
</EnableCOMDATFolding>
|
||||
<OptimizeReferences>
|
||||
</OptimizeReferences>
|
||||
<AdditionalDependencies>ws2_32.lib;sqlite3.lib;advapi32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
|
@ -86,6 +87,7 @@
|
|||
<ClCompile Include="..\..\src\http\webapp.cpp" />
|
||||
<ClCompile Include="..\..\src\logging.cpp" />
|
||||
<ClCompile Include="..\..\src\main.cpp" />
|
||||
<ClCompile Include="..\..\src\service.cpp" />
|
||||
<ClCompile Include="..\..\src\tools.c" />
|
||||
<ClCompile Include="..\..\src\tracker.cpp" />
|
||||
<ClCompile Include="..\..\src\udpTracker.cpp" />
|
||||
|
@ -98,6 +100,7 @@
|
|||
<ClInclude Include="..\..\src\http\webapp.hpp" />
|
||||
<ClInclude Include="..\..\src\logging.h" />
|
||||
<ClInclude Include="..\..\src\multiplatform.h" />
|
||||
<ClInclude Include="..\..\src\service.hpp" />
|
||||
<ClInclude Include="..\..\src\tools.h" />
|
||||
<ClInclude Include="..\..\src\tracker.hpp" />
|
||||
<ClInclude Include="..\..\src\udpTracker.hpp" />
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
<ClCompile Include="..\..\src\tracker.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\service.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\logging.h">
|
||||
|
@ -86,5 +89,8 @@
|
|||
<ClInclude Include="..\..\src\tracker.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\service.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Reference in a new issue