- made windows gui service only (removed desktop mode).
- changed watchdog to only launch if it has a command.
This commit is contained in:
parent
8040f1c5a3
commit
658a3e3e8f
|
@ -364,6 +364,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_pButtonApply">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Apply</string>
|
||||
</property>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>368</width>
|
||||
<height>485</height>
|
||||
<height>354</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -89,30 +89,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="m_pLabel_22">
|
||||
<property name="text">
|
||||
<string>&Process mode:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_pComboProcessMode</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="m_pComboProcessMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Service</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Desktop (legacy)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="m_pLabel_27">
|
||||
<property name="sizePolicy">
|
||||
|
@ -141,36 +117,6 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pGroupUserInterface">
|
||||
<property name="title">
|
||||
<string>&Startup</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_pCheckBoxAutoStart">
|
||||
<property name="text">
|
||||
<string>&Start Synergy after logging in</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_pCheckBoxAutoConnect">
|
||||
<property name="text">
|
||||
<string>&Automatically start server/client</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_pCheckBoxAutoHide">
|
||||
<property name="text">
|
||||
<string>&Hide when server/client starts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pGroupCrypto">
|
||||
<property name="enabled">
|
||||
|
@ -355,10 +301,6 @@
|
|||
<tabstop>m_pLineEditScreenName</tabstop>
|
||||
<tabstop>m_pSpinBoxPort</tabstop>
|
||||
<tabstop>m_pLineEditInterface</tabstop>
|
||||
<tabstop>m_pComboProcessMode</tabstop>
|
||||
<tabstop>m_pCheckBoxAutoStart</tabstop>
|
||||
<tabstop>m_pCheckBoxAutoConnect</tabstop>
|
||||
<tabstop>m_pCheckBoxAutoHide</tabstop>
|
||||
<tabstop>m_pLineEditCryptoPass</tabstop>
|
||||
<tabstop>m_pComboLogLevel</tabstop>
|
||||
<tabstop>m_pCheckBoxLogToFile</tabstop>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 :(
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "CMSWindowsScreen.h"
|
||||
#include "CMSWindowsDebugOutputter.h"
|
||||
#include "CMSWindowsWatchdog.h"
|
||||
#include "CMSWindowsEventQueueBuffer.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
@ -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<CDaemonApp>(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) {
|
||||
|
|
Loading…
Reference in New Issue