From 658a3e3e8f16888edf84848e788c722aa0bd1d7a Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Tue, 15 Oct 2013 15:46:02 +0000 Subject: [PATCH] - made windows gui service only (removed desktop mode). - changed watchdog to only launch if it has a command. --- src/gui/res/MainWindowBase.ui | 3 + src/gui/res/SettingsDialogBase.ui | 60 +--------- src/gui/src/AppConfig.cpp | 56 ---------- src/gui/src/AppConfig.h | 13 --- src/gui/src/MainWindow.cpp | 22 +--- src/gui/src/MainWindow.h | 1 - src/gui/src/SettingsDialog.cpp | 10 -- src/gui/src/main.cpp | 2 + src/lib/platform/CMSWindowsWatchdog.cpp | 140 ++++++++++++------------ src/lib/platform/CMSWindowsWatchdog.h | 8 +- src/lib/synergy/CDaemonApp.cpp | 22 ++-- 11 files changed, 92 insertions(+), 245 deletions(-) diff --git a/src/gui/res/MainWindowBase.ui b/src/gui/res/MainWindowBase.ui index 39587726..d437e0c0 100644 --- a/src/gui/res/MainWindowBase.ui +++ b/src/gui/res/MainWindowBase.ui @@ -364,6 +364,9 @@ + + false + &Apply diff --git a/src/gui/res/SettingsDialogBase.ui b/src/gui/res/SettingsDialogBase.ui index a8c5dcfd..c37020a6 100644 --- a/src/gui/res/SettingsDialogBase.ui +++ b/src/gui/res/SettingsDialogBase.ui @@ -7,7 +7,7 @@ 0 0 368 - 485 + 354 @@ -89,30 +89,6 @@ - - - - &Process mode: - - - m_pComboProcessMode - - - - - - - - Service - - - - - Desktop (legacy) - - - - @@ -141,36 +117,6 @@ - - - - &Startup - - - - - - &Start Synergy after logging in - - - - - - - &Automatically start server/client - - - - - - - &Hide when server/client starts - - - - - - @@ -355,10 +301,6 @@ m_pLineEditScreenName m_pSpinBoxPort m_pLineEditInterface - m_pComboProcessMode - m_pCheckBoxAutoStart - m_pCheckBoxAutoConnect - m_pCheckBoxAutoHide m_pLineEditCryptoPass m_pComboLogLevel m_pCheckBoxLogToFile diff --git a/src/gui/src/AppConfig.cpp b/src/gui/src/AppConfig.cpp index 5e6835cc..b666bb41 100644 --- a/src/gui/src/AppConfig.cpp +++ b/src/gui/src/AppConfig.cpp @@ -47,14 +47,10 @@ static const char* logLevelNames[] = AppConfig::AppConfig(QSettings* settings) : m_pSettings(settings), - m_AutoConnect(false), m_ScreenName(), m_Port(24800), m_Interface(), m_LogLevel(0), - m_AutoStart(false), - m_AutoHide(false), - m_AutoStartPrompt(false), m_WizardLastRun(0), m_CryptoPass(), m_ProcessMode(DEFAULT_PROCESS_MODE) @@ -102,62 +98,15 @@ QString AppConfig::logLevelText() const return logLevelNames[logLevel()]; } -void AppConfig::setAutoStart(bool b) -{ - m_AutoStart = b; - - // always create or delete the links/files/entries even if they exist already, - // in case it was broken. - -#if defined(Q_OS_LINUX) - - QString desktopFileName("synergy.desktop"); - QString desktopFilePath("/usr/share/applications/" + desktopFileName); - QString autoStartPath(QDir::homePath() + "/.config/autostart/" + desktopFileName); - - if (b) - { - QFile::link(desktopFilePath, autoStartPath); - } - else - { - QFile::remove(autoStartPath); - } - -#elif defined(Q_OS_WIN) - - QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat); - QString path("Synergy"); - - if (b) - { - settings.setValue(path, QCoreApplication::applicationFilePath()); - } - else - { - settings.remove(path); - } - settings.sync(); - -#endif - - // TODO: mac os x auto start -} - void AppConfig::loadSettings() { - m_AutoConnect = settings().value("autoConnect", false).toBool(); m_ScreenName = settings().value("screenName", QHostInfo::localHostName()).toString(); m_Port = settings().value("port", 24800).toInt(); m_Interface = settings().value("interface").toString(); m_LogLevel = settings().value("logLevel", 3).toInt(); // level 3: INFO m_LogToFile = settings().value("logToFile", false).toBool(); m_LogFilename = settings().value("logFilename", synergyLogDir() + "synergy.log").toString(); - m_AutoStart = settings().value("autoStart", false).toBool(); - m_AutoHide = settings().value("autoHide", true).toBool(); - m_AutoStartPrompt = settings().value("autoStartPrompt", true).toBool(); m_WizardLastRun = settings().value("wizardLastRun", 0).toInt(); - m_ProcessMode = (ProcessMode)settings().value("processMode2", DEFAULT_PROCESS_MODE).toInt(); m_CryptoPass = settings().value("cryptoPass", "").toString(); m_CryptoEnabled = settings().value("cryptoEnabled", false).toBool(); m_Language = settings().value("language", QLocale::system().name()).toString(); @@ -167,18 +116,13 @@ void AppConfig::loadSettings() void AppConfig::saveSettings() { - settings().setValue("autoConnect", m_AutoConnect); settings().setValue("screenName", m_ScreenName); settings().setValue("port", m_Port); settings().setValue("interface", m_Interface); settings().setValue("logLevel", m_LogLevel); settings().setValue("logToFile", m_LogToFile); settings().setValue("logFilename", m_LogFilename); - settings().setValue("autoStart", m_AutoStart); - settings().setValue("autoHide", m_AutoHide); - settings().setValue("autoStartPrompt", m_AutoStartPrompt); settings().setValue("wizardLastRun", kWizardVersion); - settings().setValue("processMode2", m_ProcessMode); settings().setValue("cryptoPass", m_CryptoPass); settings().setValue("cryptoEnabled", m_CryptoEnabled); settings().setValue("language", m_Language); diff --git a/src/gui/src/AppConfig.h b/src/gui/src/AppConfig.h index 4437a5de..0c0abb3f 100644 --- a/src/gui/src/AppConfig.h +++ b/src/gui/src/AppConfig.h @@ -53,7 +53,6 @@ class AppConfig ~AppConfig(); public: - bool autoConnect() const { return m_AutoConnect; } const QString& screenName() const { return m_ScreenName; } int port() const { return m_Port; } const QString& interface() const { return m_Interface; } @@ -61,9 +60,6 @@ class AppConfig bool logToFile() const { return m_LogToFile; } const QString& logFilename() const { return m_LogFilename; } QString logLevelText() const; - bool autoStart() const { return m_AutoStart; } - bool autoHide() const { return m_AutoHide; } - bool autoStartPrompt() const { return m_AutoStartPrompt; } const QString& cryptoPass() const { return m_CryptoPass; } bool cryptoEnabled() const { return m_CryptoEnabled; } QString cryptoModeString() const; @@ -84,18 +80,13 @@ class AppConfig protected: QSettings& settings() { return *m_pSettings; } - void setAutoConnect(bool b) { m_AutoConnect = b; } void setScreenName(const QString& s) { m_ScreenName = s; } void setPort(int i) { m_Port = i; } void setInterface(const QString& s) { m_Interface = s; } void setLogLevel(int i) { m_LogLevel = i; } void setLogToFile(bool b) { m_LogToFile = b; } void setLogFilename(const QString& s) { m_LogFilename = s; } - void setAutoStart(bool b); - void setAutoHide(bool b) { m_AutoHide = b; } - void setAutoStartPrompt(bool b) { m_AutoStartPrompt = b; } void setCryptoEnabled(bool b) { m_CryptoEnabled = b; } - void setProcessMode(ProcessMode p) { m_ProcessMode = p; } void setWizardHasRun() { m_WizardLastRun = kWizardVersion; } void setLanguage(const QString language) { m_Language = language; } void setPremiumEmail(const QString premiumEmail) { m_PremiumEmail = premiumEmail; } @@ -108,16 +99,12 @@ class AppConfig private: QSettings* m_pSettings; - bool m_AutoConnect; QString m_ScreenName; int m_Port; QString m_Interface; int m_LogLevel; bool m_LogToFile; QString m_LogFilename; - bool m_AutoStart; - bool m_AutoHide; - bool m_AutoStartPrompt; int m_WizardLastRun; bool m_CryptoEnabled; QString m_CryptoPass; diff --git a/src/gui/src/MainWindow.cpp b/src/gui/src/MainWindow.cpp index af8d91e8..893ad150 100644 --- a/src/gui/src/MainWindow.cpp +++ b/src/gui/src/MainWindow.cpp @@ -119,8 +119,6 @@ MainWindow::~MainWindow() void MainWindow::start(bool firstRun) { - onModeChanged(!firstRun && appConfig().autoConnect(), false); - createTrayIcon(); // always show. auto-hide only happens when we have a connection. @@ -131,8 +129,6 @@ void MainWindow::start(bool firstRun) void MainWindow::onModeChanged(bool startDesktop, bool applyService) { - refreshApplyButton(); - if (appConfig().processMode() == Service) { // form is always enabled in service mode. @@ -158,11 +154,6 @@ void MainWindow::onModeChanged(bool startDesktop, bool applyService) m_pElevateCheckBox->setEnabled(appConfig().processMode() == Service); } -void MainWindow::refreshApplyButton() -{ - m_pButtonApply->setEnabled(appConfig().processMode() == Service); -} - void MainWindow::setStatus(const QString &status) { m_pStatusLabel->setText(status); @@ -282,6 +273,7 @@ void MainWindow::setIcon(qSynergyState state) void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason) { +#ifndef Q_OS_WIN if (reason == QSystemTrayIcon::DoubleClick) { if (isVisible()) @@ -294,6 +286,7 @@ void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason) activateWindow(); } } +#endif } void MainWindow::logOutput() @@ -356,13 +349,6 @@ void MainWindow::updateStateFromLogLine(const QString &line) line.contains("connected to server")) { setSynergyState(synergyConnected); - - // only hide once after each new connection. - if (!m_AlreadyHidden && appConfig().autoHide()) - { - hide(); - m_AlreadyHidden = true; - } } } @@ -646,12 +632,14 @@ void MainWindow::setSynergyState(qSynergyState state) disconnect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStartSynergy, SLOT(trigger())); connect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStopSynergy, SLOT(trigger())); m_pButtonToggleStart->setText(tr("&Stop")); + m_pButtonApply->setEnabled((appConfig().processMode() == Service)); } else { disconnect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStopSynergy, SLOT(trigger())); connect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStartSynergy, SLOT(trigger())); m_pButtonToggleStart->setText(tr("&Start")); + m_pButtonApply->setEnabled(false); } bool connected = state == synergyConnected; @@ -693,9 +681,9 @@ void MainWindow::setFormEnabled(bool enabled) void MainWindow::setVisible(bool visible) { + QMainWindow::setVisible(visible); m_pActionMinimize->setEnabled(visible); m_pActionRestore->setEnabled(!visible); - QMainWindow::setVisible(visible); #if MAC_OS_X_VERSION_10_7 // dock hide only supported on lion :( diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index e5dd78d8..0db6420a 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -114,7 +114,6 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase void logOutput(); void logError(); void updateFound(const QString& version); - void refreshApplyButton(); protected: QSettings& settings() { return m_Settings; } diff --git a/src/gui/src/SettingsDialog.cpp b/src/gui/src/SettingsDialog.cpp index 796592ff..9f3de8c0 100644 --- a/src/gui/src/SettingsDialog.cpp +++ b/src/gui/src/SettingsDialog.cpp @@ -34,16 +34,12 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) : m_Locale.fillLanguageComboBox(m_pComboLanguage); - m_pCheckBoxAutoConnect->setChecked(appConfig().autoConnect()); m_pLineEditScreenName->setText(appConfig().screenName()); m_pSpinBoxPort->setValue(appConfig().port()); m_pLineEditInterface->setText(appConfig().interface()); - m_pComboProcessMode->setCurrentIndex(appConfig().processMode()); m_pComboLogLevel->setCurrentIndex(appConfig().logLevel()); m_pCheckBoxLogToFile->setChecked(appConfig().logToFile()); m_pLineEditLogFilename->setText(appConfig().logFilename()); - m_pCheckBoxAutoStart->setChecked(appConfig().autoStart()); - m_pCheckBoxAutoHide->setChecked(appConfig().autoHide()); m_pCheckBoxEnableCrypto->setChecked(appConfig().cryptoEnabled()); setIndexFromItemData(m_pComboLanguage, appConfig().language()); if (appConfig().cryptoEnabled()) @@ -66,16 +62,12 @@ void SettingsDialog::accept() return; } - appConfig().setAutoConnect(m_pCheckBoxAutoConnect->isChecked()); appConfig().setScreenName(m_pLineEditScreenName->text()); appConfig().setPort(m_pSpinBoxPort->value()); appConfig().setInterface(m_pLineEditInterface->text()); - appConfig().setProcessMode((ProcessMode)m_pComboProcessMode->currentIndex()); appConfig().setLogLevel(m_pComboLogLevel->currentIndex()); appConfig().setLogToFile(m_pCheckBoxLogToFile->isChecked()); appConfig().setLogFilename(m_pLineEditLogFilename->text()); - appConfig().setAutoStart(m_pCheckBoxAutoStart->isChecked()); - appConfig().setAutoHide(m_pCheckBoxAutoHide->isChecked()); appConfig().setCryptoEnabled(cryptoEnabled); appConfig().setCryptoPass(cryptoPass); appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString()); @@ -98,14 +90,12 @@ void SettingsDialog::changeEvent(QEvent* event) case QEvent::LanguageChange: { int logLevelIndex = m_pComboLogLevel->currentIndex(); - int processModeIndex = m_pComboProcessMode->currentIndex(); m_pComboLanguage->blockSignals(true); retranslateUi(this); m_pComboLanguage->blockSignals(false); m_pComboLogLevel->setCurrentIndex(logLevelIndex); - m_pComboProcessMode->setCurrentIndex(processModeIndex); break; } diff --git a/src/gui/src/main.cpp b/src/gui/src/main.cpp index 402a2a97..60cd7f6c 100644 --- a/src/gui/src/main.cpp +++ b/src/gui/src/main.cpp @@ -50,7 +50,9 @@ int main(int argc, char* argv[]) if (!waitForTray()) return -1; +#ifndef Q_OS_WIN QApplication::setQuitOnLastWindowClosed(false); +#endif QSettings settings; AppConfig appConfig(&settings); diff --git a/src/lib/platform/CMSWindowsWatchdog.cpp b/src/lib/platform/CMSWindowsWatchdog.cpp index 4aeb6123..9a6db6a8 100644 --- a/src/lib/platform/CMSWindowsWatchdog.cpp +++ b/src/lib/platform/CMSWindowsWatchdog.cpp @@ -54,8 +54,8 @@ CMSWindowsWatchdog::CMSWindowsWatchdog( m_ipcServer(ipcServer), m_ipcLogOutputter(ipcLogOutputter), m_elevateProcess(false), - m_launched(false), - m_failures(0) + m_processFailures(0), + m_processRunning(false) { } @@ -165,56 +165,70 @@ CMSWindowsWatchdog::mainLoop(void*) ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION)); while (m_monitoring) { - - // relaunch if the process was running but has stopped unexpectedly. - if ((m_launched && !isProcessRunning()) || m_session.hasChanged() || m_commandChanged) { - - std::string command = getCommand(); - if (command.empty()) { - // this appears on first launch when the user hasn't configured - // anything yet, so don't show it as a warning, only show it as - // debug to devs to let them know why nothing happened. - LOG((CLOG_DEBUG "nothing to launch, no command specified.")); + try { + + if (m_processRunning && getCommand().empty()) { + LOG((CLOG_INFO "process started but command is empty, shutting down")); shutdownExistingProcesses(); + m_processRunning = false; continue; } - try { - startProcess(command); + if (m_processFailures != 0) { + // increasing backoff period, maximum of 10 seconds. + int timeout = (m_processFailures * 2) < 10 ? (m_processFailures * 2) : 10; + LOG((CLOG_INFO "backing off, wait=%ds, failures=%d", timeout, m_processFailures)); + ARCH->sleep(timeout); } - catch (XArch& e) { - LOG((CLOG_ERR "failed to launch, error: %s", e.what().c_str())); - m_launched = false; - continue; + + if (!getCommand().empty() && ((m_processFailures != 0) || m_session.hasChanged() || m_commandChanged)) { + startProcess(); } - catch (XSynergy& e) { - LOG((CLOG_ERR "failed to launch, error: %s", e.what())); - m_launched = false; - continue; + + if (m_processRunning && !isProcessActive()) { + + m_processFailures++; + m_processRunning = false; + + LOG((CLOG_WARN "detected application not running, pid=%d", + m_processInfo.dwProcessId)); } - } - if (sendSasFunc != NULL) { + if (sendSasFunc != NULL) { - HANDLE sendSasEvent = CreateEvent(NULL, FALSE, FALSE, "Global\\SendSAS"); - if (sendSasEvent != NULL) { + HANDLE sendSasEvent = CreateEvent(NULL, FALSE, FALSE, "Global\\SendSAS"); + if (sendSasEvent != NULL) { - // use SendSAS event to wait for next session (timeout 1 second). - if (WaitForSingleObject(sendSasEvent, 1000) == WAIT_OBJECT_0) { - LOG((CLOG_DEBUG "calling SendSAS")); - sendSasFunc(FALSE); + // use SendSAS event to wait for next session (timeout 1 second). + if (WaitForSingleObject(sendSasEvent, 1000) == WAIT_OBJECT_0) { + LOG((CLOG_DEBUG "calling SendSAS")); + sendSasFunc(FALSE); + } + + CloseHandle(sendSasEvent); + continue; } - - CloseHandle(sendSasEvent); - continue; } - } - // if the sas event failed, wait by sleeping. - ARCH->sleep(1); + // if the sas event failed, wait by sleeping. + ARCH->sleep(1); + + } + catch (XArch& e) { + LOG((CLOG_ERR "failed to launch, error: %s", e.what().c_str())); + m_processFailures++; + m_processRunning = false; + continue; + } + catch (XSynergy& e) { + LOG((CLOG_ERR "failed to launch, error: %s", e.what())); + m_processFailures++; + m_processRunning = false; + continue; + } } - if (m_launched) { + if (m_processRunning) { LOG((CLOG_DEBUG "terminated running process on exit")); shutdownProcess(m_processInfo.hProcess, m_processInfo.dwProcessId, 20); } @@ -223,47 +237,26 @@ CMSWindowsWatchdog::mainLoop(void*) } bool -CMSWindowsWatchdog::isProcessRunning() +CMSWindowsWatchdog::isProcessActive() { - bool running; - if (m_launched) { - - DWORD exitCode; - GetExitCodeProcess(m_processInfo.hProcess, &exitCode); - running = (exitCode == STILL_ACTIVE); - - if (!running && !m_command.empty()) { - m_failures++; - LOG((CLOG_INFO - "detected application not running, pid=%d, failures=%d", - m_processInfo.dwProcessId, m_failures)); - - // increasing backoff period, maximum of 10 seconds. - int timeout = (m_failures * 2) < 10 ? (m_failures * 2) : 10; - LOG((CLOG_DEBUG "waiting, backoff period is %d seconds", timeout)); - ARCH->sleep(timeout); - - // double check, in case process started after we waited. - GetExitCodeProcess(m_processInfo.hProcess, &exitCode); - running = (exitCode == STILL_ACTIVE); - } - else { - // reset failures when running. - m_failures = 0; - } - } - return running; + DWORD exitCode; + GetExitCodeProcess(m_processInfo.hProcess, &exitCode); + return exitCode == STILL_ACTIVE; } void -CMSWindowsWatchdog::startProcess(std::string& command) +CMSWindowsWatchdog::startProcess() { + if (m_command.empty()) { + throw XMSWindowsWatchdogError("cannot start process, command is empty"); + } + m_commandChanged = false; - if (m_launched) { + if (m_processRunning) { LOG((CLOG_DEBUG "closing existing process to make way for new one")); shutdownProcess(m_processInfo.hProcess, m_processInfo.dwProcessId, 20); - m_launched = false; + m_processRunning = false; } m_session.updateActiveSession(); @@ -299,7 +292,7 @@ CMSWindowsWatchdog::startProcess(std::string& command) // re-launch in current active user session LOG((CLOG_INFO "starting new process")); BOOL createRet = CreateProcessAsUser( - userToken, NULL, LPSTR(command.c_str()), + userToken, NULL, LPSTR(m_command.c_str()), &sa, NULL, TRUE, creationFlags, environment, NULL, &si, &m_processInfo); @@ -311,9 +304,11 @@ CMSWindowsWatchdog::startProcess(std::string& command) throw XArch(new XArchEvalWindows); } else { + m_processRunning = true; + m_processFailures = 0; + LOG((CLOG_DEBUG "started process, session=%i, command=%s", - m_session.getActiveSessionId(), command.c_str())); - m_launched = true; + m_session.getActiveSessionId(), m_command.c_str())); } } @@ -470,4 +465,5 @@ CMSWindowsWatchdog::shutdownExistingProcesses() } CloseHandle(snapshot); + m_processRunning = false; } diff --git a/src/lib/platform/CMSWindowsWatchdog.h b/src/lib/platform/CMSWindowsWatchdog.h index 24752348..b92012c1 100644 --- a/src/lib/platform/CMSWindowsWatchdog.h +++ b/src/lib/platform/CMSWindowsWatchdog.h @@ -49,8 +49,8 @@ private: void shutdownExistingProcesses(); HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security); HANDLE getUserToken(LPSECURITY_ATTRIBUTES security); - void startProcess(std::string& command); - bool isProcessRunning(); + void startProcess(); + bool isProcessActive(); void sendSas(); private: @@ -66,9 +66,9 @@ private: CIpcLogOutputter& m_ipcLogOutputter; bool m_elevateProcess; CMSWindowsSession m_session; - bool m_launched; PROCESS_INFORMATION m_processInfo; - int m_failures; + int m_processFailures; + bool m_processRunning; }; //! Relauncher error diff --git a/src/lib/synergy/CDaemonApp.cpp b/src/lib/synergy/CDaemonApp.cpp index 93bcf8df..f5d6ded5 100644 --- a/src/lib/synergy/CDaemonApp.cpp +++ b/src/lib/synergy/CDaemonApp.cpp @@ -45,6 +45,7 @@ #include "CMSWindowsScreen.h" #include "CMSWindowsDebugOutputter.h" #include "CMSWindowsWatchdog.h" +#include "CMSWindowsEventQueueBuffer.h" #define WIN32_LEAN_AND_MEAN #include @@ -191,10 +192,7 @@ CDaemonApp::mainLoop(bool logToFile) try { DAEMON_RUNNING(true); - /*while (true) - { - }*/ - + if (logToFile) CLOG->insert(new CFileLogOutputter(logPath().c_str())); @@ -208,22 +206,21 @@ CDaemonApp::mainLoop(bool logToFile) // send logging to gui via ipc, log system adopts outputter. m_ipcLogOutputter = new CIpcLogOutputter(*m_ipcServer); CLOG->insert(m_ipcLogOutputter); - + #if SYSAPI_WIN32 m_watchdog = new CMSWindowsWatchdog(false, *m_ipcServer, *m_ipcLogOutputter); #endif - + m_events->adoptHandler( m_events->forCIpcServer().messageReceived(), m_ipcServer, new TMethodEventJob(this, &CDaemonApp::handleIpcMessage)); m_ipcServer->listen(); - + #if SYSAPI_WIN32 - // HACK: create a dummy screen, which can handle system events - // (such as a stop request from the service controller). - CMSWindowsScreen::init(CArchMiscWindows::instanceWin32()); - CScreen dummyScreen(new CMSWindowsScreen(false, true, false, m_events), m_events); + + // install the platform event queue to handle service stop events. + m_events->adoptBuffer(new CMSWindowsEventQueueBuffer(m_events)); CString command = ARCH->setting("Command"); bool elevate = ARCH->setting("Elevate") == "1"; @@ -234,7 +231,6 @@ CDaemonApp::mainLoop(bool logToFile) m_watchdog->startAsync(); #endif - m_events->loop(); #if SYSAPI_WIN32 @@ -248,7 +244,7 @@ CDaemonApp::mainLoop(bool logToFile) CLOG->remove(m_ipcLogOutputter); delete m_ipcLogOutputter; delete m_ipcServer; - + DAEMON_RUNNING(false); } catch (XArch& e) {