public IResult Run(IRunnerStartInfo runnerStartInfo) { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = false; startInfo.UseShellExecute = false; startInfo.FileName = Path.Combine("..", "..", "..", "Tools", "timeout", "timeout"); startInfo.Arguments = string.Format(" -t {0} -m {1} --detect-hangups ", runnerStartInfo.WorkingTimeLimit / 1000, runnerStartInfo.MemoryLimit) + " " + runnerStartInfo.ExecutableFile + " " + runnerStartInfo.Arguments; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardError = true; IResult result = new Result(); try { Process process = Process.Start(startInfo); process.StandardInput.WriteLine(runnerStartInfo.InputString); int maximumUserTime = runnerStartInfo.WorkingTimeLimit * UserWorkingTimeKoef; bool killed = false; while (process.HasExited == false) { try { double realWorkingTime = (DateTime.Now - process.StartTime).TotalMilliseconds; if (realWorkingTime > maximumUserTime) { result.PeakMemoryUsed = 0; result.WorkingTime = (int)realWorkingTime; process.Kill(); killed = true; } Thread.Sleep(500); } catch (InvalidOperationException) { result.PeakMemoryUsed = Math.Max(result.PeakMemoryUsed, 1); result.WorkingTime = Math.Max(result.WorkingTime, 15); } } result.ExitCode = process.ExitCode; if (killed) result.ExitCode = -1; if (result.ExitCode != -1) { result.OutputString = process.StandardOutput.ReadToEnd(); string standardErrorOutput = process.StandardError.ReadToEnd().TrimEnd(); string[] errorOutputLines = standardErrorOutput.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); int timeoutOutputLines = 2; if (!errorOutputLines[errorOutputLines.Length - 1].Contains("<time ")) timeoutOutputLines = 1; //need only first lines without last two lines result.ErrorOutputString = ""; for (int i = 0; i < errorOutputLines.Length - timeoutOutputLines; i++) result.ErrorOutputString = string.Concat(result.ErrorOutputString, errorOutputLines[i], Environment.NewLine); //only last two lines string timeoutOutputResults = errorOutputLines[errorOutputLines.Length - timeoutOutputLines]; if (timeoutOutputLines > 1) timeoutOutputResults += string.Concat(Environment.NewLine, errorOutputLines[errorOutputLines.Length - 1]); result = ParseOutputFromTimeout(timeoutOutputResults, result); } process.Dispose(); } catch { throw; } return result; }
public IResult Run(IRunnerStartInfo runnerStartInfo) { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.CreateNoWindow = false; startInfo.UseShellExecute = false; startInfo.FileName = runnerStartInfo.ExecutableFile; startInfo.Arguments = runnerStartInfo.Arguments; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardInput = true; startInfo.RedirectStandardError = true; IResult result = new Result(); try { Process process = Process.Start(startInfo); process.StandardInput.WriteLine(runnerStartInfo.InputString); int maximumUserTime = runnerStartInfo.WorkingTimeLimit * UserWorkingTimeKoef; while(process.HasExited == false) { try { double realWorkingTime = (DateTime.Now - process.StartTime).TotalMilliseconds; result.PeakMemoryUsed = Math.Max(result.PeakMemoryUsed, process.PeakVirtualMemorySize64 / (1024 * 1024)); if (realWorkingTime > maximumUserTime) { result.WorkingTime = maximumUserTime; process.Kill(); } else if (process.TotalProcessorTime.TotalMilliseconds > runnerStartInfo.WorkingTimeLimit /*|| result.PeakMemoryUsed > runnerStartInfo.MemoryLimit*/) { result.WorkingTime = (int)(process.TotalProcessorTime.TotalMilliseconds); process.Kill(); } Thread.Sleep(50); } catch(InvalidOperationException) { //result.PeakMemoryUsed = Math.Max(result.PeakMemoryUsed, 1); result.WorkingTime = Math.Max(result.WorkingTime, 15); } } result.ExitCode = process.ExitCode; if (result.ExitCode != -1) { result.OutputString = process.StandardOutput.ReadToEnd(); result.ErrorOutputString = process.StandardError.ReadToEnd(); result.WorkingTime = (int)(process.TotalProcessorTime.TotalMilliseconds); result.WorkingTime = Math.Max(result.WorkingTime, 15); } process.Dispose(); } catch { throw; } return result; }