static RundotnetData RunDotNet(RundotnetData data)
        {
            int compilationTimeInMs;
            CompilerParameters cp = new CompilerParameters();

            cp.GenerateExecutable = false;
            Random rg           = Utils.Utils.GetTrulyRandom();
            string folder       = reExp.Utils.Utils.RootFolder + @"\executables\usercode\";
            string assemblyName = "userAssembly_" + rg.Next(0, 10000000);

            string path = folder + assemblyName + ".dll";

            cp.OutputAssembly = path;
            // Save the assembly as a physical file.
            cp.GenerateInMemory = false;
            // Set whether to treat all warnings as errors.
            cp.TreatWarningsAsErrors   = false;
            cp.WarningLevel            = 4;
            cp.IncludeDebugInformation = false;


            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("System.Core.dll");

            cp.ReferencedAssemblies.Add("System.Numerics.dll");
            cp.ReferencedAssemblies.Add("System.Data.dll");
            cp.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll");
            cp.ReferencedAssemblies.Add("System.Xml.dll");
            cp.ReferencedAssemblies.Add("System.Xml.Linq.dll");
            cp.ReferencedAssemblies.Add("System.Drawing.dll");

            if (data.LanguageChoice == LanguagesEnum.CSharp)
            {
                cp.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
            }
            else if (data.LanguageChoice == LanguagesEnum.VB)
            {
                cp.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
            }

            cp.ReferencedAssemblies.Add(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute).Assembly.Location);
            cp.ReferencedAssemblies.Add(typeof(System.ComponentModel.Composition.ImportAttribute).Assembly.Location);
            cp.ReferencedAssemblies.Add(typeof(System.Web.HttpRequest).Assembly.Location);
            cp.ReferencedAssemblies.Add(typeof(System.Net.Http.HttpClient).Assembly.Location);
            cp.ReferencedAssemblies.Add(typeof(Newtonsoft.Json.JsonSerializer).Assembly.Location);

            //cp.ReferencedAssemblies.Add(typeof(System.Windows.Threading.DispatcherTimer).Assembly.Location);

            CompilerResults cr = null;

            using (var provider = GetProvider(data.LanguageChoice))
            {
                DateTime comp_start = DateTime.Now;
                // Invoke compilation of the source file.
                cr = provider.CompileAssemblyFromSource(cp, new string[] { data.Program });
                compilationTimeInMs = (int)(DateTime.Now - comp_start).TotalMilliseconds;
            }

            var messages = cr.Errors.Cast <CompilerError>();
            var warnings = messages.Where(f => f.IsWarning == true);
            var errors   = messages.Where(f => f.IsWarning == false);

            if (warnings.Count() != 0)
            {
                foreach (var warn in warnings)
                {
                    data.Warnings.Add(string.Format("({0}:{1}) {2}", warn.Line, warn.Column, warn.ErrorText));
                }
            }
            if (errors.Count() != 0)
            {
                foreach (var ce in errors)
                {
                    data.Errors.Add(string.Format("({0}:{1}) {2}", ce.Line, ce.Column, ce.ErrorText));
                }
                Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, "Compilation errors", (int)data.LanguageChoice, data.IsApi, false);
                data.RunStats = string.Format("Compilation time: {0} s", Math.Round((compilationTimeInMs / (double)1000), 2));
                return(data);
            }
            else
            {
                using (Process process = new Process())
                {
                    try
                    {
                        double TotalMemoryInBytes = 0;
                        double TotalThreadCount   = 0;
                        int    samplesCount       = 0;

                        process.StartInfo.FileName               = reExp.Utils.Utils.RootFolder + "executables/SpawnedProcess.exe";
                        process.StartInfo.Arguments              = folder.Replace(" ", "|_|") + " " + assemblyName + " Rextester|Program|Main";
                        process.StartInfo.UseShellExecute        = false;
                        process.StartInfo.CreateNoWindow         = true;
                        process.StartInfo.RedirectStandardOutput = true;
                        process.StartInfo.RedirectStandardError  = true;
                        process.StartInfo.RedirectStandardInput  = true;

                        DateTime start = DateTime.Now;
                        process.Start();
                        //try
                        //{
                        //    process.PriorityClass = ProcessPriorityClass.BelowNormal;
                        //}
                        //catch (Exception)
                        //{ }

                        if (!string.IsNullOrEmpty(data.Input))
                        {
                            InputWriter input       = new InputWriter(process.StandardInput, data.Input);
                            Thread      inputWriter = new Thread(new ThreadStart(input.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();


                        do
                        {
                            // Refresh the current process property values.
                            process.Refresh();
                            if (!process.HasExited)
                            {
                                try
                                {
                                    var proc = process.TotalProcessorTime;
                                    // Update the values for the overall peak memory statistics.
                                    var mem1 = process.PagedMemorySize64;
                                    var mem2 = process.PrivateMemorySize64;

                                    //update stats
                                    TotalMemoryInBytes += (mem1 + mem2);
                                    TotalThreadCount   += (process.Threads.Count);
                                    samplesCount++;

                                    if (proc.TotalSeconds > 5 || mem1 + mem2 > 100000000 || process.Threads.Count > 100 || start + TimeSpan.FromSeconds(10) < DateTime.Now)
                                    {
                                        var time = proc.TotalSeconds;
                                        var mem  = mem1 + mem2;
                                        process.Kill();
                                        var res = string.Format("Process killed because it exceeded given resources.\nCpu time used {0} sec, absolute running time {1} sec, memory used {2} Mb, nr of threads {3}", time, (int)(DateTime.Now - start).TotalSeconds, (int)(mem / 1048576), process.Threads.Count);
                                        data.Errors.Add(res);
                                        string partialResult = output.Builder.ToString();
                                        data.Output = partialResult;
                                        Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, res, (int)data.LanguageChoice, data.IsApi, false);
                                        data.RunStats = string.Format("Compilation time: {0} sec, absolute running time: {1} sec, cpu time: {2} sec, average memory usage: {3} Mb, average nr of threads: {4}",
                                                                      Math.Round((compilationTimeInMs / (double)1000), 2),
                                                                      Math.Round((DateTime.Now - start).TotalSeconds, 2),
                                                                      Math.Round(proc.TotalSeconds, 2),
                                                                      samplesCount != 0 ? (int?)((TotalMemoryInBytes / samplesCount) / 1048576) : null,
                                                                      samplesCount != 0 ? (int?)(TotalThreadCount / samplesCount) : null);
                                        return(data);
                                    }
                                }
                                catch (InvalidOperationException)
                                {
                                    break;
                                }
                            }
                        }while (!process.WaitForExit(10));
                        process.WaitForExit();

                        data.RunStats = string.Format("Compilation time: {0} sec, absolute running time: {1} sec, cpu time: {2} sec, average memory usage: {3} Mb, average nr of threads: {4}",
                                                      Math.Round((compilationTimeInMs / (double)1000), 2),
                                                      Math.Round((process.ExitTime - process.StartTime).TotalSeconds, 2),
                                                      Math.Round(process.TotalProcessorTime.TotalSeconds, 2),
                                                      samplesCount != 0 ? (int?)((TotalMemoryInBytes / samplesCount) / 1048576) : null,
                                                      samplesCount != 0 ? (int?)(TotalThreadCount / samplesCount) : null);

                        errorReader.Join(5000);
                        outputReader.Join(5000);
                        if (!string.IsNullOrEmpty(error.Output))
                        {
                            data.Output = output.Builder.ToString();
                            data.Errors.Add(error.Output);
                            Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, error.Output, (int)data.LanguageChoice, data.IsApi, false);
                            return(data);
                        }
                        data.Output = output.Output;
                        Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, "OK", (int)data.LanguageChoice, data.IsApi, true);
                        return(data);
                    }
                    catch (Exception e)
                    {
                        if (!process.HasExited)
                        {
                            reExp.Utils.Log.LogInfo("Process left running " + e.Message, e, "RunDotNet");
                        }
                        throw;
                    }
                    finally
                    {
                        reExp.Utils.CleanUp.DeleteFile(path);
                    }
                }
            }
        }
示例#2
0
        static RundotnetData RunDotNet(RundotnetData data)
        {
            int compilationTimeInMs;
            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = false;
            Random rg = Utils.Utils.GetTrulyRandom();
            string folder = reExp.Utils.Utils.RootFolder + @"\executables\usercode\";
            string assemblyName = "userAssembly_" + rg.Next(0, 10000000);

            string path = folder + assemblyName + ".dll";
            cp.OutputAssembly = path;
            // Save the assembly as a physical file.
            cp.GenerateInMemory = false;
            // Set whether to treat all warnings as errors.
            cp.TreatWarningsAsErrors = false;
            cp.WarningLevel = 4;
            cp.IncludeDebugInformation = false;

            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("System.Core.dll");

            cp.ReferencedAssemblies.Add("System.Numerics.dll");
            cp.ReferencedAssemblies.Add("System.Data.dll");
            cp.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll");
            cp.ReferencedAssemblies.Add("System.Xml.dll");
            cp.ReferencedAssemblies.Add("System.Xml.Linq.dll");
            cp.ReferencedAssemblies.Add("System.Drawing.dll");

            if (data.LanguageChoice == LanguagesEnum.CSharp)
                cp.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
            else if (data.LanguageChoice == LanguagesEnum.VB)
                cp.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");

            cp.ReferencedAssemblies.Add(typeof(System.ComponentModel.DataAnnotations.DisplayAttribute).Assembly.Location);
            cp.ReferencedAssemblies.Add(typeof(System.ComponentModel.Composition.ImportAttribute).Assembly.Location);
            cp.ReferencedAssemblies.Add(typeof(System.Web.HttpRequest).Assembly.Location);
            cp.ReferencedAssemblies.Add(typeof(System.Net.Http.HttpClient).Assembly.Location);
            cp.ReferencedAssemblies.Add(typeof(Newtonsoft.Json.JsonSerializer).Assembly.Location);

            //cp.ReferencedAssemblies.Add(typeof(System.Windows.Threading.DispatcherTimer).Assembly.Location);

            CompilerResults cr = null;

            using (var provider = GetProvider(data.LanguageChoice))
            {
                DateTime comp_start = DateTime.Now;
                // Invoke compilation of the source file.
                cr = provider.CompileAssemblyFromSource(cp, new string[] { data.Program });
                compilationTimeInMs = (int)(DateTime.Now - comp_start).TotalMilliseconds;
            }

            var messages = cr.Errors.Cast<CompilerError>();
            var warnings = messages.Where(f => f.IsWarning == true);
            var errors = messages.Where(f => f.IsWarning == false);

            if (warnings.Count() != 0)
            {
                foreach (var warn in warnings)
                    data.Warnings.Add(string.Format("({0}:{1}) {2}", warn.Line, warn.Column, warn.ErrorText));
            }
            if (errors.Count() != 0)
            {
                foreach (var ce in errors)
                {
                    data.Errors.Add(string.Format("({0}:{1}) {2}", ce.Line, ce.Column, ce.ErrorText));
                }
                Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, "Compilation errors", (int)data.LanguageChoice, data.IsApi, false);
                data.RunStats = string.Format("Compilation time: {0} s", Math.Round((compilationTimeInMs / (double)1000), 2));
                return data;
            }
            else
            {
                using (Process process = new Process())
                {
                    try
                    {
                        double TotalMemoryInBytes = 0;
                        double TotalThreadCount = 0;
                        int samplesCount = 0;

                        process.StartInfo.FileName = reExp.Utils.Utils.RootFolder + "executables/SpawnedProcess.exe";
                        process.StartInfo.Arguments = folder.Replace(" ", "|_|") + " " + assemblyName + " Rextester|Program|Main";
                        process.StartInfo.UseShellExecute = false;
                        process.StartInfo.CreateNoWindow = true;
                        process.StartInfo.RedirectStandardOutput = true;
                        process.StartInfo.RedirectStandardError = true;
                        process.StartInfo.RedirectStandardInput = true;

                        DateTime start = DateTime.Now;
                        process.Start();
                        //try
                        //{
                        //    process.PriorityClass = ProcessPriorityClass.BelowNormal;
                        //}
                        //catch (Exception)
                        //{ }

                        if (!string.IsNullOrEmpty(data.Input))
                        {
                            InputWriter input = new InputWriter(process.StandardInput, data.Input);
                            Thread inputWriter = new Thread(new ThreadStart(input.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();

                        do
                        {
                            // Refresh the current process property values.
                            process.Refresh();
                            if (!process.HasExited)
                            {
                                try
                                {
                                    var proc = process.TotalProcessorTime;
                                    // Update the values for the overall peak memory statistics.
                                    var mem1 = process.PagedMemorySize64;
                                    var mem2 = process.PrivateMemorySize64;

                                    //update stats
                                    TotalMemoryInBytes += (mem1 + mem2);
                                    TotalThreadCount += (process.Threads.Count);
                                    samplesCount++;

                                    if (proc.TotalSeconds > 5 || mem1 + mem2 > 100000000 || process.Threads.Count > 100 || start + TimeSpan.FromSeconds(10) < DateTime.Now)
                                    {
                                        var time = proc.TotalSeconds;
                                        var mem = mem1 + mem2;
                                        process.Kill();
                                        var res = string.Format("Process killed because it exceeded given resources.\nCpu time used {0} sec, absolute running time {1} sec, memory used {2} Mb, nr of threads {3}", time, (int)(DateTime.Now - start).TotalSeconds, (int)(mem / 1048576), process.Threads.Count);
                                        data.Errors.Add(res);
                                        string partialResult = output.Builder.ToString();
                                        data.Output = partialResult;
                                        Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, res, (int)data.LanguageChoice, data.IsApi, false);
                                        data.RunStats = string.Format("Compilation time: {0} sec, absolute running time: {1} sec, cpu time: {2} sec, average memory usage: {3} Mb, average nr of threads: {4}",
                                            Math.Round((compilationTimeInMs / (double)1000), 2),
                                            Math.Round((DateTime.Now - start).TotalSeconds, 2),
                                            Math.Round(proc.TotalSeconds, 2),
                                            samplesCount != 0 ? (int?)((TotalMemoryInBytes / samplesCount) / 1048576) : null,
                                            samplesCount != 0 ? (int?)(TotalThreadCount / samplesCount) : null);
                                        return data;
                                    }
                                }
                                catch (InvalidOperationException)
                                {
                                    break;
                                }
                            }
                        }
                        while (!process.WaitForExit(10));
                        process.WaitForExit();

                        data.RunStats = string.Format("Compilation time: {0} sec, absolute running time: {1} sec, cpu time: {2} sec, average memory usage: {3} Mb, average nr of threads: {4}",
                                            Math.Round((compilationTimeInMs / (double)1000), 2),
                                            Math.Round((process.ExitTime - process.StartTime).TotalSeconds, 2),
                                            Math.Round(process.TotalProcessorTime.TotalSeconds, 2),
                                            samplesCount != 0 ? (int?)((TotalMemoryInBytes / samplesCount) / 1048576) : null,
                                            samplesCount != 0 ? (int?)(TotalThreadCount / samplesCount) : null);

                        errorReader.Join(5000);
                        outputReader.Join(5000);
                        if (!string.IsNullOrEmpty(error.Output))
                        {
                            data.Output = output.Builder.ToString();
                            data.Errors.Add(error.Output);
                            Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, error.Output, (int)data.LanguageChoice, data.IsApi, false);
                            return data;
                        }
                        data.Output = output.Output;
                        Utils.Log.LogCodeToDB(data.Program, data.Input, data.CompilerArgs, "OK", (int)data.LanguageChoice, data.IsApi, true);
                        return data;
                    }
                    catch (Exception e)
                    {
                        if (!process.HasExited)
                        {
                            reExp.Utils.Log.LogInfo("Process left running " + e.Message, e, "RunDotNet");
                        }
                        throw;
                    }
                    finally
                    {
                        reExp.Utils.CleanUp.DeleteFile(path);
                    }
                }
            }
        }