#6383 Use CreateProcess when in foreground mode
This commit is contained in:
parent
568a008037
commit
026b1f0de1
|
@ -49,7 +49,8 @@ const char g_activeDesktop[] = {"activeDesktop:"};
|
||||||
MSWindowsWatchdog::MSWindowsWatchdog(
|
MSWindowsWatchdog::MSWindowsWatchdog(
|
||||||
bool autoDetectCommand,
|
bool autoDetectCommand,
|
||||||
IpcServer& ipcServer,
|
IpcServer& ipcServer,
|
||||||
IpcLogOutputter& ipcLogOutputter) :
|
IpcLogOutputter& ipcLogOutputter,
|
||||||
|
bool foreground) :
|
||||||
m_thread(NULL),
|
m_thread(NULL),
|
||||||
m_autoDetectCommand(autoDetectCommand),
|
m_autoDetectCommand(autoDetectCommand),
|
||||||
m_monitoring(true),
|
m_monitoring(true),
|
||||||
|
@ -63,7 +64,8 @@ MSWindowsWatchdog::MSWindowsWatchdog(
|
||||||
m_processRunning(false),
|
m_processRunning(false),
|
||||||
m_fileLogOutputter(NULL),
|
m_fileLogOutputter(NULL),
|
||||||
m_autoElevated(false),
|
m_autoElevated(false),
|
||||||
m_ready(false)
|
m_ready(false),
|
||||||
|
m_foreground(foreground)
|
||||||
{
|
{
|
||||||
m_mutex = ARCH->newMutex();
|
m_mutex = ARCH->newMutex();
|
||||||
m_condVar = ARCH->newCondVar();
|
m_condVar = ARCH->newCondVar();
|
||||||
|
@ -200,9 +202,23 @@ MSWindowsWatchdog::mainLoop(void*)
|
||||||
ARCH->sleep(timeout);
|
ARCH->sleep(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getCommand().empty() && ((m_processFailures != 0) || m_session.hasChanged() || m_commandChanged)) {
|
if (!getCommand().empty()) {
|
||||||
|
bool startNeeded = false;
|
||||||
|
|
||||||
|
if (m_processFailures != 0) {
|
||||||
|
startNeeded = true;
|
||||||
|
}
|
||||||
|
else if (!m_foreground && m_session.hasChanged()) {
|
||||||
|
startNeeded = true;
|
||||||
|
}
|
||||||
|
else if (m_commandChanged) {
|
||||||
|
startNeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startNeeded) {
|
||||||
startProcess();
|
startProcess();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (m_processRunning && !isProcessActive()) {
|
if (m_processRunning && !isProcessActive()) {
|
||||||
|
|
||||||
|
@ -284,6 +300,13 @@ MSWindowsWatchdog::startProcess()
|
||||||
m_processRunning = false;
|
m_processRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL createRet;
|
||||||
|
if (m_foreground) {
|
||||||
|
LOG((CLOG_DEBUG "starting command in foreground"));
|
||||||
|
createRet = startProcessInForeground(m_command);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG((CLOG_DEBUG "starting command as session user"));
|
||||||
m_session.updateActiveSession();
|
m_session.updateActiveSession();
|
||||||
|
|
||||||
SECURITY_ATTRIBUTES sa;
|
SECURITY_ATTRIBUTES sa;
|
||||||
|
@ -298,14 +321,14 @@ MSWindowsWatchdog::startProcess()
|
||||||
|
|
||||||
// patch by Jack Zhou and Henry Tung
|
// patch by Jack Zhou and Henry Tung
|
||||||
// set UIAccess to fix Windows 8 GUI interaction
|
// set UIAccess to fix Windows 8 GUI interaction
|
||||||
// http://symless.com/spit/issues/details/3338/#c70
|
|
||||||
DWORD uiAccess = 1;
|
DWORD uiAccess = 1;
|
||||||
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
|
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
|
||||||
|
|
||||||
BOOL createRet = doStartProcess(m_command, userToken, &sa);
|
createRet = startProcessAsUser(m_command, userToken, &sa);
|
||||||
|
}
|
||||||
|
|
||||||
if (!createRet) {
|
if (!createRet) {
|
||||||
LOG((CLOG_ERR "could not launch"));
|
LOG((CLOG_ERR "could not launch command"));
|
||||||
DWORD exitCode = 0;
|
DWORD exitCode = 0;
|
||||||
GetExitCodeProcess(m_processInfo.hProcess, &exitCode);
|
GetExitCodeProcess(m_processInfo.hProcess, &exitCode);
|
||||||
LOG((CLOG_ERR "exit code: %d", exitCode));
|
LOG((CLOG_ERR "exit code: %d", exitCode));
|
||||||
|
@ -329,7 +352,21 @@ MSWindowsWatchdog::startProcess()
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
MSWindowsWatchdog::doStartProcess(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa)
|
MSWindowsWatchdog::startProcessInForeground(String& command)
|
||||||
|
{
|
||||||
|
// clear, as we're reusing process info struct
|
||||||
|
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
||||||
|
|
||||||
|
STARTUPINFO startupInfo;
|
||||||
|
ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
|
||||||
|
|
||||||
|
return CreateProcess(
|
||||||
|
NULL, LPSTR(command.c_str()), NULL, NULL,
|
||||||
|
FALSE, 0, NULL, NULL, &startupInfo, &m_processInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
MSWindowsWatchdog::startProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa)
|
||||||
{
|
{
|
||||||
// clear, as we're reusing process info struct
|
// clear, as we're reusing process info struct
|
||||||
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
||||||
|
@ -542,7 +579,7 @@ MSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
|
||||||
HANDLE userToken = getUserToken(security);
|
HANDLE userToken = getUserToken(security);
|
||||||
m_elevateProcess = elevateProcess;
|
m_elevateProcess = elevateProcess;
|
||||||
|
|
||||||
BOOL createRet = doStartProcess(syntoolCommand, userToken, security);
|
BOOL createRet = startProcessAsUser(syntoolCommand, userToken, security);
|
||||||
|
|
||||||
if (!createRet) {
|
if (!createRet) {
|
||||||
DWORD rc = GetLastError();
|
DWORD rc = GetLastError();
|
||||||
|
|
|
@ -37,7 +37,8 @@ public:
|
||||||
MSWindowsWatchdog(
|
MSWindowsWatchdog(
|
||||||
bool autoDetectCommand,
|
bool autoDetectCommand,
|
||||||
IpcServer& ipcServer,
|
IpcServer& ipcServer,
|
||||||
IpcLogOutputter& ipcLogOutputter);
|
IpcLogOutputter& ipcLogOutputter,
|
||||||
|
bool foreground);
|
||||||
virtual ~MSWindowsWatchdog();
|
virtual ~MSWindowsWatchdog();
|
||||||
|
|
||||||
void startAsync();
|
void startAsync();
|
||||||
|
@ -55,7 +56,8 @@ private:
|
||||||
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
|
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
|
||||||
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security);
|
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security);
|
||||||
void startProcess();
|
void startProcess();
|
||||||
BOOL doStartProcess(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
|
BOOL startProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
|
||||||
|
BOOL startProcessInForeground(String& command);
|
||||||
void sendSas();
|
void sendSas();
|
||||||
void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
|
void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
|
||||||
void testOutput(String buffer);
|
void testOutput(String buffer);
|
||||||
|
@ -81,6 +83,7 @@ private:
|
||||||
ArchMutex m_mutex;
|
ArchMutex m_mutex;
|
||||||
ArchCond m_condVar;
|
ArchCond m_condVar;
|
||||||
bool m_ready;
|
bool m_ready;
|
||||||
|
bool m_foreground;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Relauncher error
|
//! Relauncher error
|
||||||
|
|
|
@ -155,7 +155,7 @@ DaemonApp::run(int argc, char** argv)
|
||||||
if (foreground) {
|
if (foreground) {
|
||||||
// run process in foreground instead of daemonizing.
|
// run process in foreground instead of daemonizing.
|
||||||
// useful for debugging.
|
// useful for debugging.
|
||||||
mainLoop(false);
|
mainLoop(false, foreground);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
|
@ -192,7 +192,7 @@ DaemonApp::run(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DaemonApp::mainLoop(bool logToFile)
|
DaemonApp::mainLoop(bool logToFile, bool foreground)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -215,7 +215,7 @@ DaemonApp::mainLoop(bool logToFile)
|
||||||
CLOG->insert(m_ipcLogOutputter);
|
CLOG->insert(m_ipcLogOutputter);
|
||||||
|
|
||||||
#if SYSAPI_WIN32
|
#if SYSAPI_WIN32
|
||||||
m_watchdog = new MSWindowsWatchdog(false, *m_ipcServer, *m_ipcLogOutputter);
|
m_watchdog = new MSWindowsWatchdog(false, *m_ipcServer, *m_ipcLogOutputter, foreground);
|
||||||
m_watchdog->setFileLogOutputter(m_fileLogOutputter);
|
m_watchdog->setFileLogOutputter(m_fileLogOutputter);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
DaemonApp();
|
DaemonApp();
|
||||||
virtual ~DaemonApp();
|
virtual ~DaemonApp();
|
||||||
int run(int argc, char** argv);
|
int run(int argc, char** argv);
|
||||||
void mainLoop(bool logToFile);
|
void mainLoop(bool logToFile, bool foreground = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void daemonize();
|
void daemonize();
|
||||||
|
|
Loading…
Reference in New Issue