Use ManualResetEvent for external scripting process timeouts.

This commit is contained in:
Jared Goodwin 2020-03-04 23:03:24 -08:00
parent f3abdb2836
commit f73d7c14b4
3 changed files with 21 additions and 39 deletions

View File

@ -44,7 +44,7 @@ namespace Remotely.Agent.Services
private string ConnectionID { get; set; }
private string ErrorOut { get; set; }
private string LastInputID { get; set; }
private bool OutputDone { get; set; }
private ManualResetEvent OutputDone { get; } = new ManualResetEvent(false);
private System.Timers.Timer ProcessIdleTimeout { get; set; }
private string StandardOut { get; set; }
public static Bash GetCurrent(string connectionID)
@ -72,17 +72,12 @@ namespace Remotely.Agent.Services
lock (BashProc)
{
LastInputID = commandID;
OutputDone = false;
OutputDone.Reset();
BashProc.StandardInput.WriteLine(input);
BashProc.StandardInput.WriteLine("echo " + commandID);
var startWait = DateTime.Now;
while (!OutputDone)
if (!OutputDone.WaitOne(TimeSpan.FromSeconds(30)))
{
if (DateTime.Now - startWait > TimeSpan.FromSeconds(30))
{
return GeneratePartialResult();
}
Thread.Sleep(1);
return GeneratePartialResult();
}
}
return GenerateCompletedResult();
@ -100,9 +95,9 @@ namespace Remotely.Agent.Services
{
if (e?.Data?.Contains(LastInputID) == true)
{
OutputDone = true;
OutputDone.Set();
}
else if (!OutputDone)
else
{
StandardOut += e.Data + Environment.NewLine;
}
@ -123,14 +118,13 @@ namespace Remotely.Agent.Services
private GenericCommandResult GeneratePartialResult()
{
OutputDone = true;
var partialResult = new GenericCommandResult()
{
CommandContextID = LastInputID,
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
CommandType = "Bash",
StandardOutput = StandardOut,
ErrorOutput = "WARNING: The command execution froze and was forced to return before finishing. " +
ErrorOutput = "WARNING: The command execution timed out and was forced to return before finishing. " +
"The results may be partial, and the console process has been reset. " +
"Please note that interactive commands aren't supported." + Environment.NewLine + ErrorOut
};

View File

@ -46,7 +46,7 @@ namespace Remotely.Agent.Services
private string ErrorOut { get; set; }
private string LastInputID { get; set; }
private bool OutputDone { get; set; }
private ManualResetEvent OutputDone { get; } = new ManualResetEvent(false);
private System.Timers.Timer ProcessIdleTimeout { get; set; }
private string StandardOut { get; set; }
public static CMD GetCurrent(string connectionID)
@ -74,17 +74,12 @@ namespace Remotely.Agent.Services
lock (CMDProc)
{
LastInputID = commandID;
OutputDone = false;
OutputDone.Reset();
CMDProc.StandardInput.WriteLine(input);
CMDProc.StandardInput.WriteLine("echo " + commandID);
var startWait = DateTime.Now;
while (!OutputDone)
if (!OutputDone.WaitOne(TimeSpan.FromSeconds(30)))
{
if (DateTime.Now - startWait > TimeSpan.FromSeconds(30))
{
return GeneratePartialResult();
}
Thread.Sleep(1);
return GeneratePartialResult();
}
return GenerateCompletedResult();
}
@ -103,9 +98,9 @@ namespace Remotely.Agent.Services
{
if (e?.Data?.Contains(LastInputID) == true)
{
OutputDone = true;
OutputDone.Set();
}
else if (!OutputDone)
else
{
StandardOut += e.Data + Environment.NewLine;
}
@ -126,14 +121,13 @@ namespace Remotely.Agent.Services
private GenericCommandResult GeneratePartialResult()
{
OutputDone = true;
var partialResult = new GenericCommandResult()
{
CommandContextID = LastInputID,
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
CommandType = "CMD",
StandardOutput = StandardOut,
ErrorOutput = "WARNING: The command execution froze and was forced to return before finishing. " +
ErrorOutput = "WARNING: The command execution timed out and was forced to return before finishing. " +
"The results may be partial, and the console process has been reset. " +
"Please note that interactive commands aren't supported." + Environment.NewLine + ErrorOut
};

View File

@ -43,7 +43,7 @@ namespace Remotely.Agent.Services
private string ConnectionID { get; set; }
private string ErrorOut { get; set; }
private string LastInputID { get; set; }
private bool OutputDone { get; set; }
private ManualResetEvent OutputDone { get; } = new ManualResetEvent(false);
private System.Timers.Timer ProcessIdleTimeout { get; set; }
private Process PSProc { get; }
private string StandardOut { get; set; }
@ -73,17 +73,12 @@ namespace Remotely.Agent.Services
lock (PSProc)
{
LastInputID = commandID;
OutputDone = false;
OutputDone.Reset();
PSProc.StandardInput.WriteLine(input);
PSProc.StandardInput.WriteLine("echo " + commandID);
var startWait = DateTime.Now;
while (!OutputDone)
if (!OutputDone.WaitOne(TimeSpan.FromSeconds(30)))
{
if (DateTime.Now - startWait > TimeSpan.FromSeconds(30))
{
return GeneratePartialResult();
}
Thread.Sleep(1);
return GeneratePartialResult();
}
}
@ -102,9 +97,9 @@ namespace Remotely.Agent.Services
{
if (e?.Data?.Contains(LastInputID) == true)
{
OutputDone = true;
OutputDone.Set();
}
else if (!OutputDone)
else
{
StandardOut += e.Data + Environment.NewLine;
}
@ -124,14 +119,13 @@ namespace Remotely.Agent.Services
private GenericCommandResult GeneratePartialResult()
{
OutputDone = true;
var partialResult = new GenericCommandResult()
{
CommandContextID = LastInputID,
DeviceID = ConfigService.GetConnectionInfo().DeviceID,
CommandType = "WinPS",
StandardOutput = StandardOut,
ErrorOutput = "WARNING: The command execution froze and was forced to return before finishing. " +
ErrorOutput = "WARNING: The command execution timed out and was forced to return before finishing. " +
"The results may be partial, and the console process has been reset. " +
"Please note that interactive commands aren't supported." + Environment.NewLine + ErrorOut
};