static void ExecuteCode(string nr, string input) { try { string path = @"C:\inetpub\wwwroot\rextester\usercode\"; Console.WriteLine("Sandbox start: " + nr); using (Process process = new Process()) using (var job = new Job()) { process.StartInfo.FileName = Path.Combine(path, nr, "a.exe"); Console.WriteLine(process.StartInfo.FileName); process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardInput = true; Console.WriteLine("Sandbox: job start " + nr); process.Start(); job.AddProcess(process.Handle); if (!string.IsNullOrEmpty(input)) { InputWriter iw = new InputWriter(process.StandardInput, input); Thread inputWriter = new Thread(new ThreadStart(iw.Writeinput)); inputWriter.Start(); } OutputReader output = new OutputReader(process.StandardOutput); Thread outputReader = new Thread(new ThreadStart(output.ReadOutput)); outputReader.Start(); OutputReader error = new OutputReader(process.StandardError); Thread errorReader = new Thread(new ThreadStart(error.ReadOutput)); errorReader.Start(); var start = DateTime.Now; bool killed = false; string Errors = ""; string Output = ""; do { // Refresh the current process property values. process.Refresh(); if (!process.HasExited) { try { if (start + TimeSpan.FromSeconds(20) < DateTime.Now) { process.Kill(); var res = string.Format("Process killed because it ran longer than 20 seconds"); Errors = res; Output = output.Builder.ToString(); killed = true; } } catch (InvalidOperationException) { break; } } }while (!process.WaitForExit(10)); process.WaitForExit(); Console.WriteLine("Sandbox: job over " + nr); if (!killed) { errorReader.Join(5000); outputReader.Join(5000); if (process.ExitCode != 0) { error.Output = string.Format("Process exit code is not 0: {0}\n", process.ExitCode) + error.Output; } Errors = error.Output; Output = output.Output; } if (!string.IsNullOrEmpty(Errors)) { Console.WriteLine("Sandbox: writing errors " + nr); RedisConnection.Strings.Set(3, nr, Encoding.UTF8.GetBytes(Errors)); } if (!string.IsNullOrEmpty(Output)) { Console.WriteLine("Sandbox: writing output " + nr); RedisConnection.Strings.Set(2, nr, Encoding.UTF8.GetBytes(Output)); } RedisConnection.Strings.Set(4, nr, new byte[] { (byte)1 }); } } catch (Exception ex) { Console.WriteLine("Sandbox: error " + nr + " " + ex.Message); try { RedisConnection.Strings.Set(4, nr, new byte[] { (byte)1 }); } catch (Exception) { } } finally { //ThreadPool.QueueUserWorkItem(f => { // CleanSandbox(); //}); } }
static void ExecuteCode(string nr, string input) { try { string path = @"C:\inetpub\wwwroot\rextester\usercode\"; Console.WriteLine("Sandbox start: " + nr); using (Process process = new Process()) using (var job = new Job()) { process.StartInfo.FileName = Path.Combine(path, nr, "a.exe"); Console.WriteLine(process.StartInfo.FileName); process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardInput = true; Console.WriteLine("Sandbox: job start " + nr); process.Start(); job.AddProcess(process.Handle); if (!string.IsNullOrEmpty(input)) { InputWriter iw = new InputWriter(process.StandardInput, input); Thread inputWriter = new Thread(new ThreadStart(iw.Writeinput)); inputWriter.Start(); } OutputReader output = new OutputReader(process.StandardOutput); Thread outputReader = new Thread(new ThreadStart(output.ReadOutput)); outputReader.Start(); OutputReader error = new OutputReader(process.StandardError); Thread errorReader = new Thread(new ThreadStart(error.ReadOutput)); errorReader.Start(); var start = DateTime.Now; bool killed = false; string Errors = ""; string Output = ""; do { // Refresh the current process property values. process.Refresh(); if (!process.HasExited) { try { if (start + TimeSpan.FromSeconds(20) < DateTime.Now) { process.Kill(); var res = string.Format("Process killed because it ran longer than 20 seconds"); Errors = res; Output = output.Builder.ToString(); killed = true; } } catch (InvalidOperationException) { break; } } } while (!process.WaitForExit(10)); process.WaitForExit(); Console.WriteLine("Sandbox: job over " + nr); if (!killed) { errorReader.Join(5000); outputReader.Join(5000); if (process.ExitCode != 0) error.Output = string.Format("Process exit code is not 0: {0}\n", process.ExitCode) + error.Output; Errors = error.Output; Output = output.Output; } if (!string.IsNullOrEmpty(Errors)) { Console.WriteLine("Sandbox: writing errors " + nr); RedisConnection.Strings.Set(3, nr, Encoding.UTF8.GetBytes(Errors)); } if (!string.IsNullOrEmpty(Output)) { Console.WriteLine("Sandbox: writing output " + nr); RedisConnection.Strings.Set(2, nr, Encoding.UTF8.GetBytes(Output)); } RedisConnection.Strings.Set(4, nr, new byte[] { (byte)1 }); } } catch (Exception ex) { Console.WriteLine("Sandbox: error " + nr + " " + ex.Message); try { RedisConnection.Strings.Set(4, nr, new byte[] { (byte)1 }); } catch (Exception) { } } finally { //ThreadPool.QueueUserWorkItem(f => { // CleanSandbox(); //}); } }