chore: Remove unused daemon installation and uninstallation methods
This commit is contained in:
parent
539ddcaf48
commit
ad383ad9d4
8 changed files with 3 additions and 340 deletions
|
|
@ -59,12 +59,6 @@ int main(int argc, char **argv)
|
||||||
const auto foregroundOption = QCommandLineOption({"f", "foreground"}, "Run in the foreground (show console)");
|
const auto foregroundOption = QCommandLineOption({"f", "foreground"}, "Run in the foreground (show console)");
|
||||||
parser.addOption(foregroundOption);
|
parser.addOption(foregroundOption);
|
||||||
|
|
||||||
const auto installOption = QCommandLineOption({"i", "install"}, "Install as a Windows service");
|
|
||||||
parser.addOption(installOption);
|
|
||||||
|
|
||||||
const auto uninstallOption = QCommandLineOption({"u", "uninstall"}, "Uninstall the Windows service");
|
|
||||||
parser.addOption(uninstallOption);
|
|
||||||
|
|
||||||
parser.process(app);
|
parser.process(app);
|
||||||
|
|
||||||
if (parser.isSet(foregroundOption)) {
|
if (parser.isSet(foregroundOption)) {
|
||||||
|
|
@ -83,7 +77,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
// Default log level to system setting (found in Registry).
|
// Default log level to system setting (found in Registry).
|
||||||
auto logLevel = Settings::value(Settings::Daemon::LogLevel).toString().toStdString();
|
auto logLevel = Settings::value(Settings::Daemon::LogLevel).toString().toStdString();
|
||||||
if (logLevel != "") {
|
if (!logLevel.empty()) {
|
||||||
CLOG->setFilter(logLevel.c_str());
|
CLOG->setFilter(logLevel.c_str());
|
||||||
LOG_DEBUG("log level: %s", logLevel.c_str());
|
LOG_DEBUG("log level: %s", logLevel.c_str());
|
||||||
}
|
}
|
||||||
|
|
@ -97,14 +91,6 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (parser.isSet(installOption)) {
|
|
||||||
daemon.install();
|
|
||||||
return s_exitSuccess;
|
|
||||||
} else if (parser.isSet(uninstallOption)) {
|
|
||||||
daemon.uninstall();
|
|
||||||
return s_exitSuccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto ipcServer = new ipc::DaemonIpcServer(&app, qPrintable(DaemonApp::logFilename())); // NOSONAR - Qt managed
|
const auto ipcServer = new ipc::DaemonIpcServer(&app, qPrintable(DaemonApp::logFilename())); // NOSONAR - Qt managed
|
||||||
ipcServer->listen();
|
ipcServer->listen();
|
||||||
daemon.connectIpcServer(ipcServer);
|
daemon.connectIpcServer(ipcServer);
|
||||||
|
|
|
||||||
|
|
@ -11,16 +11,6 @@
|
||||||
// ArchDaemonNone
|
// ArchDaemonNone
|
||||||
//
|
//
|
||||||
|
|
||||||
void ArchDaemonNone::installDaemon(const char *, const char *, const char *, const char *, const char *)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArchDaemonNone::uninstallDaemon(const char *)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
int ArchDaemonNone::daemonize(const char *name, DaemonFunc const &func)
|
int ArchDaemonNone::daemonize(const char *name, DaemonFunc const &func)
|
||||||
{
|
{
|
||||||
// simply forward the call to func. obviously, this doesn't
|
// simply forward the call to func. obviously, this doesn't
|
||||||
|
|
@ -28,26 +18,6 @@ int ArchDaemonNone::daemonize(const char *name, DaemonFunc const &func)
|
||||||
return func(1, &name);
|
return func(1, &name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArchDaemonNone::canInstallDaemon(const char *)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArchDaemonNone::isDaemonInstalled(const char *)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArchDaemonNone::installDaemon()
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArchDaemonNone::uninstallDaemon()
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ArchDaemonNone::commandLine() const
|
std::string ArchDaemonNone::commandLine() const
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,8 @@
|
||||||
|
|
||||||
//! Dummy implementation of IArchDaemon
|
//! Dummy implementation of IArchDaemon
|
||||||
/*!
|
/*!
|
||||||
This class implements IArchDaemon for a platform that does not have
|
This class implements IArchDaemon for a platform that does not have daemons.
|
||||||
daemons. The install and uninstall functions do nothing, the query
|
The query functions return false, and \c daemonize() simply calls the passed
|
||||||
functions return false, and \c daemonize() simply calls the passed
|
|
||||||
function and returns its result.
|
function and returns its result.
|
||||||
*/
|
*/
|
||||||
class ArchDaemonNone : public IArchDaemon
|
class ArchDaemonNone : public IArchDaemon
|
||||||
|
|
@ -25,14 +24,6 @@ public:
|
||||||
~ArchDaemonNone() override = default;
|
~ArchDaemonNone() override = default;
|
||||||
|
|
||||||
// IArchDaemon overrides
|
// IArchDaemon overrides
|
||||||
void installDaemon(
|
|
||||||
const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies
|
|
||||||
) override;
|
|
||||||
void uninstallDaemon(const char *name) override;
|
|
||||||
int daemonize(const char *name, DaemonFunc const &func) override;
|
int daemonize(const char *name, DaemonFunc const &func) override;
|
||||||
bool canInstallDaemon(const char *name) override;
|
|
||||||
bool isDaemonInstalled(const char *name) override;
|
|
||||||
void installDaemon() override;
|
|
||||||
void uninstallDaemon() override;
|
|
||||||
std::string commandLine() const override;
|
std::string commandLine() const override;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -26,41 +26,6 @@ public:
|
||||||
//! @name manipulators
|
//! @name manipulators
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
//! Install daemon
|
|
||||||
/*!
|
|
||||||
Install a daemon. \c name is the name of the daemon passed to the
|
|
||||||
system and \c description is a short human readable description of
|
|
||||||
the daemon. \c pathname is the path to the daemon executable.
|
|
||||||
\c commandLine should \b not include the name of program as the
|
|
||||||
first argument. If \c allUsers is true then the daemon will be
|
|
||||||
installed to start at boot time, otherwise it will be installed to
|
|
||||||
start when the current user logs in. If \p dependencies is not nullptr
|
|
||||||
then it's a concatenation of NUL terminated other daemon names
|
|
||||||
followed by a NUL; the daemon will be configured to startup after
|
|
||||||
the listed daemons. Throws an \c ArchDaemonException exception on failure.
|
|
||||||
*/
|
|
||||||
virtual void installDaemon(
|
|
||||||
const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
//! Uninstall daemon
|
|
||||||
/*!
|
|
||||||
Uninstall a daemon. Throws an \c ArchDaemonException on failure.
|
|
||||||
*/
|
|
||||||
virtual void uninstallDaemon(const char *name) = 0;
|
|
||||||
|
|
||||||
//! Install daemon
|
|
||||||
/*!
|
|
||||||
Installs the default daemon.
|
|
||||||
*/
|
|
||||||
virtual void installDaemon() = 0;
|
|
||||||
|
|
||||||
//! Uninstall daemon
|
|
||||||
/*!
|
|
||||||
Uninstalls the default daemon.
|
|
||||||
*/
|
|
||||||
virtual void uninstallDaemon() = 0;
|
|
||||||
|
|
||||||
//! Daemonize the process
|
//! Daemonize the process
|
||||||
/*!
|
/*!
|
||||||
Daemonize. Throw ArchDaemonFailedException on error. \c name is the name
|
Daemonize. Throw ArchDaemonFailedException on error. \c name is the name
|
||||||
|
|
@ -90,22 +55,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual int daemonize(const char *name, DaemonFunc const &func) = 0;
|
virtual int daemonize(const char *name, DaemonFunc const &func) = 0;
|
||||||
|
|
||||||
//! Check if user has permission to install the daemon
|
|
||||||
/*!
|
|
||||||
Returns true iff the caller has permission to install or
|
|
||||||
uninstall the daemon. Note that even if this method returns
|
|
||||||
true it's possible that installing/uninstalling the service
|
|
||||||
may still fail. This method ignores whether or not the
|
|
||||||
service is already installed.
|
|
||||||
*/
|
|
||||||
virtual bool canInstallDaemon(const char *name) = 0;
|
|
||||||
|
|
||||||
//! Check if the daemon is installed
|
|
||||||
/*!
|
|
||||||
Returns true iff the daemon is installed.
|
|
||||||
*/
|
|
||||||
virtual bool isDaemonInstalled(const char *name) = 0;
|
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
//! Get the command line
|
//! Get the command line
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,7 @@
|
||||||
#include "arch/win32/ArchMiscWindows.h"
|
#include "arch/win32/ArchMiscWindows.h"
|
||||||
#include "arch/win32/XArchWindows.h"
|
#include "arch/win32/XArchWindows.h"
|
||||||
#include "base/Log.h"
|
#include "base/Log.h"
|
||||||
#include "common/Constants.h"
|
|
||||||
|
|
||||||
inline static const auto kDefaultDaemonName = _T(kAppName);
|
|
||||||
//
|
//
|
||||||
// ArchDaemonWindows
|
// ArchDaemonWindows
|
||||||
//
|
//
|
||||||
|
|
@ -54,142 +52,6 @@ void ArchDaemonWindows::daemonFailed(int result)
|
||||||
throw ArchDaemonRunException(result);
|
throw ArchDaemonRunException(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchDaemonWindows::installDaemon(
|
|
||||||
const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("installing windows service: %s", name);
|
|
||||||
|
|
||||||
// open service manager
|
|
||||||
SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_WRITE);
|
|
||||||
if (mgr == nullptr) {
|
|
||||||
// can't open service manager
|
|
||||||
throw ArchDaemonInstallException(windowsErrorToString(GetLastError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the service
|
|
||||||
SC_HANDLE service = CreateService(
|
|
||||||
mgr, name, name, 0, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START,
|
|
||||||
SERVICE_ERROR_NORMAL, pathname, nullptr, nullptr, dependencies, nullptr, nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
if (service == nullptr) {
|
|
||||||
// can't create service
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
if (err != ERROR_SERVICE_EXISTS) {
|
|
||||||
CloseServiceHandle(mgr);
|
|
||||||
throw ArchDaemonInstallException(windowsErrorToString(err));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// done with service (but only try to close if not null)
|
|
||||||
CloseServiceHandle(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
// done with manager
|
|
||||||
CloseServiceHandle(mgr);
|
|
||||||
|
|
||||||
// open the registry key for this service
|
|
||||||
HKEY key = openNTServicesKey();
|
|
||||||
key = ArchMiscWindows::addKey(key, name);
|
|
||||||
if (key == nullptr) {
|
|
||||||
// can't open key
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
try {
|
|
||||||
uninstallDaemon(name);
|
|
||||||
} catch (...) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
throw ArchDaemonInstallException(windowsErrorToString(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the description
|
|
||||||
ArchMiscWindows::setValue(key, _T("Description"), description);
|
|
||||||
|
|
||||||
// set command line
|
|
||||||
key = ArchMiscWindows::addKey(key, _T("Parameters"));
|
|
||||||
if (key == nullptr) {
|
|
||||||
// can't open key
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
ArchMiscWindows::closeKey(key);
|
|
||||||
try {
|
|
||||||
uninstallDaemon(name);
|
|
||||||
} catch (...) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
throw ArchDaemonInstallException(windowsErrorToString(err));
|
|
||||||
}
|
|
||||||
ArchMiscWindows::setValue(key, _T("CommandLine"), commandLine);
|
|
||||||
|
|
||||||
// done with registry
|
|
||||||
ArchMiscWindows::closeKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArchDaemonWindows::uninstallDaemon(const char *name)
|
|
||||||
{
|
|
||||||
LOG_DEBUG("uninstalling windows service: %s", name);
|
|
||||||
|
|
||||||
// remove parameters for this service. ignore failures.
|
|
||||||
HKEY key = openNTServicesKey();
|
|
||||||
key = ArchMiscWindows::openKey(key, name);
|
|
||||||
if (key != nullptr) {
|
|
||||||
ArchMiscWindows::deleteKey(key, _T("Parameters"));
|
|
||||||
ArchMiscWindows::closeKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
// open service manager
|
|
||||||
SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_WRITE);
|
|
||||||
if (mgr == nullptr) {
|
|
||||||
// can't open service manager
|
|
||||||
throw ArchDaemonUninstallFailedException(windowsErrorToString(GetLastError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the service. oddly, you must open a service to delete it.
|
|
||||||
SC_HANDLE service = OpenService(mgr, name, DELETE | SERVICE_STOP);
|
|
||||||
if (service == nullptr) {
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
CloseServiceHandle(mgr);
|
|
||||||
if (err != ERROR_SERVICE_DOES_NOT_EXIST) {
|
|
||||||
throw ArchDaemonUninstallFailedException(windowsErrorToString(err));
|
|
||||||
}
|
|
||||||
throw ArchDaemonUninstallNotInstalledException(windowsErrorToString(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop the service. we don't care if we fail.
|
|
||||||
SERVICE_STATUS status;
|
|
||||||
ControlService(service, SERVICE_CONTROL_STOP, &status);
|
|
||||||
|
|
||||||
// delete the service
|
|
||||||
const bool okay = (DeleteService(service) == 0);
|
|
||||||
const DWORD err = GetLastError();
|
|
||||||
|
|
||||||
// clean up
|
|
||||||
CloseServiceHandle(service);
|
|
||||||
CloseServiceHandle(mgr);
|
|
||||||
|
|
||||||
// give windows a chance to remove the service before we check if it still exists.
|
|
||||||
// 100ms should be plenty of time.
|
|
||||||
LOG_DEBUG("waiting for service to be removed");
|
|
||||||
Arch::sleep(0.1);
|
|
||||||
|
|
||||||
// handle failure. ignore error if service isn't installed anymore.
|
|
||||||
if (!okay && isDaemonInstalled(name)) {
|
|
||||||
if (err == ERROR_SUCCESS) {
|
|
||||||
// this seems to occur even though the uninstall was successful.
|
|
||||||
// it could be a timing issue, i.e., isDaemonInstalled is
|
|
||||||
// called too soon. i've added a sleep to try and stop this.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (err == ERROR_IO_PENDING) {
|
|
||||||
// this seems to be a spurious error
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (err != ERROR_SERVICE_MARKED_FOR_DELETE) {
|
|
||||||
throw ArchDaemonUninstallFailedException(windowsErrorToString(err));
|
|
||||||
}
|
|
||||||
throw ArchDaemonUninstallNotInstalledException(windowsErrorToString(err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ArchDaemonWindows::daemonize(const char *name, DaemonFunc const &func)
|
int ArchDaemonWindows::daemonize(const char *name, DaemonFunc const &func)
|
||||||
{
|
{
|
||||||
assert(name != nullptr);
|
assert(name != nullptr);
|
||||||
|
|
@ -218,42 +80,6 @@ int ArchDaemonWindows::daemonize(const char *name, DaemonFunc const &func)
|
||||||
return m_daemonResult;
|
return m_daemonResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArchDaemonWindows::canInstallDaemon(const char * /*name*/)
|
|
||||||
{
|
|
||||||
// check if we can open service manager for write
|
|
||||||
SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_WRITE);
|
|
||||||
if (mgr == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
CloseServiceHandle(mgr);
|
|
||||||
|
|
||||||
// check if we can open the registry key
|
|
||||||
HKEY key = openNTServicesKey();
|
|
||||||
ArchMiscWindows::closeKey(key);
|
|
||||||
|
|
||||||
return (key != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ArchDaemonWindows::isDaemonInstalled(const char *name)
|
|
||||||
{
|
|
||||||
// open service manager
|
|
||||||
SC_HANDLE mgr = OpenSCManager(nullptr, nullptr, GENERIC_READ);
|
|
||||||
if (mgr == nullptr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the service
|
|
||||||
SC_HANDLE service = OpenService(mgr, name, GENERIC_READ);
|
|
||||||
|
|
||||||
// clean up
|
|
||||||
if (service != nullptr) {
|
|
||||||
CloseServiceHandle(service);
|
|
||||||
}
|
|
||||||
CloseServiceHandle(mgr);
|
|
||||||
|
|
||||||
return (service != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
HKEY ArchDaemonWindows::openNTServicesKey()
|
HKEY ArchDaemonWindows::openNTServicesKey()
|
||||||
{
|
{
|
||||||
static const char *s_keyNames[] = {_T("SYSTEM"), _T("CurrentControlSet"), _T("Services"), nullptr};
|
static const char *s_keyNames[] = {_T("SYSTEM"), _T("CurrentControlSet"), _T("Services"), nullptr};
|
||||||
|
|
@ -602,35 +428,3 @@ void ArchDaemonWindows::stop(const char *name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchDaemonWindows::installDaemon()
|
|
||||||
{
|
|
||||||
// install default daemon if not already installed.
|
|
||||||
if (!isDaemonInstalled(kDefaultDaemonName)) {
|
|
||||||
char binPath[MAX_PATH];
|
|
||||||
GetModuleFileName(ArchMiscWindows::instanceWin32(), binPath, MAX_PATH);
|
|
||||||
|
|
||||||
// wrap in quotes so a malicious user can't start \Program.exe as admin.
|
|
||||||
const auto command = "\"" + std::string(binPath) + "\"";
|
|
||||||
|
|
||||||
installDaemon(kDefaultDaemonName, DEFAULT_DAEMON_INFO, command.c_str(), "", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
start(kDefaultDaemonName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArchDaemonWindows::uninstallDaemon()
|
|
||||||
{
|
|
||||||
// remove legacy services if installed.
|
|
||||||
if (isDaemonInstalled(LEGACY_SERVER_DAEMON_NAME)) {
|
|
||||||
uninstallDaemon(LEGACY_SERVER_DAEMON_NAME);
|
|
||||||
}
|
|
||||||
if (isDaemonInstalled(LEGACY_CLIENT_DAEMON_NAME)) {
|
|
||||||
uninstallDaemon(LEGACY_CLIENT_DAEMON_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove new service if installed.
|
|
||||||
if (isDaemonInstalled(kDefaultDaemonName)) {
|
|
||||||
uninstallDaemon(kDefaultDaemonName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -67,15 +67,7 @@ public:
|
||||||
static UINT getDaemonQuitMessage();
|
static UINT getDaemonQuitMessage();
|
||||||
|
|
||||||
// IArchDaemon overrides
|
// IArchDaemon overrides
|
||||||
void installDaemon(
|
|
||||||
const char *name, const char *description, const char *pathname, const char *commandLine, const char *dependencies
|
|
||||||
) override;
|
|
||||||
void uninstallDaemon(const char *name) override;
|
|
||||||
void installDaemon() override;
|
|
||||||
void uninstallDaemon() override;
|
|
||||||
int daemonize(const char *name, DaemonFunc const &func) override;
|
int daemonize(const char *name, DaemonFunc const &func) override;
|
||||||
bool canInstallDaemon(const char *name) override;
|
|
||||||
bool isDaemonInstalled(const char *name) override;
|
|
||||||
std::string commandLine() const override
|
std::string commandLine() const override
|
||||||
{
|
{
|
||||||
return m_commandLine;
|
return m_commandLine;
|
||||||
|
|
@ -134,8 +126,3 @@ private:
|
||||||
|
|
||||||
std::string m_commandLine;
|
std::string m_commandLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_DAEMON_INFO _T("Runs the Core process on secure desktops (UAC prompts, login screen, etc).")
|
|
||||||
|
|
||||||
#define LEGACY_SERVER_DAEMON_NAME _T("Deskflow Server")
|
|
||||||
#define LEGACY_CLIENT_DAEMON_NAME _T("Deskflow Client")
|
|
||||||
|
|
|
||||||
|
|
@ -122,18 +122,6 @@ void DaemonApp::connectIpcServer(const ipc::DaemonIpcServer *ipcServer) const
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DaemonApp::install() const
|
|
||||||
{
|
|
||||||
LOG_NOTE("installing windows daemon");
|
|
||||||
ARCH->installDaemon();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DaemonApp::uninstall() const
|
|
||||||
{
|
|
||||||
LOG_NOTE("uninstalling windows daemon");
|
|
||||||
ARCH->uninstallDaemon();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DaemonApp::run(QThread &daemonThread)
|
void DaemonApp::run(QThread &daemonThread)
|
||||||
{
|
{
|
||||||
LOG_NOTE("starting daemon");
|
LOG_NOTE("starting daemon");
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,6 @@ public:
|
||||||
~DaemonApp() override;
|
~DaemonApp() override;
|
||||||
|
|
||||||
InitResult init(int argc, char **argv);
|
InitResult init(int argc, char **argv);
|
||||||
void install() const;
|
|
||||||
void uninstall() const;
|
|
||||||
void run(QThread &daemonThread);
|
void run(QThread &daemonThread);
|
||||||
void setForeground();
|
void setForeground();
|
||||||
void initLogging();
|
void initLogging();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue