protected virtual RunResult ExecuteCodeBlock(RunOptsBase opts, CodeHelper codeHelper) { RunResult result; result = codeHelper.Run(opts); return(result); }
public static RunResult ExecuteCode(RunOptsBase opts, Type codeHelperType) { AppDomain sandboxDomain = SandboxHelper.CreateSandboxDomain(true, GetMappings()); try { var containerType = typeof(Container); ObjectHandle handle = Activator.CreateInstanceFrom( sandboxDomain, containerType.Assembly.ManifestModule.FullyQualifiedName, containerType.FullName); var container = handle.Unwrap() as Container; container.InitWorkerSettings( WorkerConfiguration.Current.ID, WorkerConfiguration.Current.SandboxFolder, codeHelperType); var runResult = container.Run(opts); return(runResult); } finally { SandboxHelper.UnloadDomain(sandboxDomain); } }
protected virtual bool CheckCodeBlock(RunOptsBase opts, ref RunResult runResult) { if (opts.CodeBlock == null) { opts.CodeBlock = new ConsoleOrScriptCodeBlock { CodeBlock = string.Empty } } ; else if (((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock == null) { ((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock = string.Empty; } return(CheckCodeSizeLimit(((ConsoleOrScriptCodeBlock)opts.CodeBlock).CodeBlock, ref runResult)); }
public static RunResult RunInThread(CodeHelper codeHelper, RunOptsBase runOpts) { RunResult result = null; try { codeHelper.RequestedConsoleInput += CodeHelper_RequestedConsoleInput; var newThread = new Thread(() => { result = codeHelper.Run(runOpts); }); newThread.Start(); newThread.Join(TimeSpan.FromSeconds(10)); } finally { codeHelper.RequestedConsoleInput -= CodeHelper_RequestedConsoleInput; } return(result); }
protected override bool CheckCodeBlock(RunOptsBase opts, ref RunResult runResult) { if (opts.CodeBlock == null) { opts.CodeBlock = new MvcCodeBlock { Model = string.Empty, View = string.Empty, Controller = string.Empty } } ; var codeBlock = (MvcCodeBlock)opts.CodeBlock; return(CheckCodeSizeLimit(codeBlock.Model, ref runResult) && CheckCodeSizeLimit(codeBlock.Controller, ref runResult)); }
public RunResult Run(RunOptsBase opts) { RunResult result = null; if (!CheckCodeBlock(opts, ref result)) { return(result); } // we should copy it before running, becuase it can be changed during execution var sandboxFolder = _sandboxFolder; var codeHelper = SandboxHelper.ExecuteInFullTrust(() => (CodeHelper)Activator.CreateInstance(_codeHelperType)); codeHelper.NuGetDllReferences = opts.NuGetDllReferences; codeHelper.StartingExecution += this.CodeHelper_StartingExecution; codeHelper.FinishedExecution += this.CodeHelper_FinishedExecution; codeHelper.RequestedConsoleInput += this.CodeHelper_RequestedConsoleInput; _executingThread = new Thread( () => { try { _runAt = DateTime.Now; result = this.ExecuteCodeBlock(opts, codeHelper); } finally { // in theory in can be null at this point if something bad happened.... if (result == null) { result = new RunResult() { FailureType = RunResultFailureType.FatalError, IsSuccess = false }; } result.Stats = SandboxHelper.ExecuteInFullTrust(() => GatherStatistics()); _compilationCompleted.Set(); } }); _executingThread.Start(); var monitoringTask = Task.Factory.StartNew(MonitorHealth, _tokenSource.Token); // wait for compilation. Just to be sure we have 15 seconds timeout _compilationCompleted.WaitOne(TimeSpan.FromSeconds(15)); // if something happened during compilation, then we fire _compilationCompleted on exit, and result will be filled, so we just need to return it if (result != null) { return(result); } // it will use some time for compilation // it can hungs for some unmanaged call like Console.ReadKey(), so we wait with timeout // we might need to rewrite it to ManualEvent that will be fired when CodeHelper starts execution _executingThread.Join(WorkerConfiguration.Current.ExecutionLimitTimeoutMs * 2); _tokenSource.Cancel(); // we can't move it to new method, as it can be executed via reflection SandboxHelper.ExecuteInFullTrust( () => { try { if (Directory.Exists(sandboxFolder)) { foreach (var file in Directory.EnumerateFiles(sandboxFolder, "*", SearchOption.AllDirectories)) { File.Delete(file); } } } catch { if (result != null) { result.SandboxUnloadReason = SandboxUnloadReason.ClearDirFailed; } } }); return(result); }
protected override void RunInteractive(RunOptsBase opts, RunResult result) { new PermissionSet(PermissionState.Unrestricted).Assert(); CommonScriptEngine scriptEngine = this.CreateSciptEngine(); Session session = scriptEngine.CreateSession(); var codeBlock = (ConsoleOrScriptCodeBlock)opts.CodeBlock; var referencedDlls = this.GetGacDlls(codeBlock.CodeBlock); foreach (var referenceDll in referencedDlls) { session.AddReference(referenceDll); } var libs = GetNonGacDlls(); foreach (var path in libs) { session.AddReference(path); } Submission <object> submission; try { // we compile code there submission = session.CompileSubmission <object>(codeBlock.CodeBlock); } catch (ThreadAbortException) { throw; } catch (Exception ex) { if (!string.IsNullOrEmpty(ex.Message) && ex.Message.Contains(ErrorWhenCompileConsoleProjectAsScript)) { /*Case 4067: DotNetFiddle throws exception on VbNet Script * https://entech.fogbugz.com/default.asp?4067#31607 * This issue occurs, when user is trying to compile VB.Net Console project as VB.Net Script project. * So, there is main entry point 'Module Sub Main' in snippet. * Then Roslyn throws following exception "(3) : error BC35000: Requested operation is not available because the runtime library function 'Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute..ctor' is not defined." * In same case for C#, Roslyn just ignores 'console' code. * So for VB.Net case we just return 'success' and empty string. */ result.IsSuccess = true; result.ConsoleOutput = ""; } else { ValidateCodeResult validateCodeResult = ValidateCode(codeBlock.CodeBlock); result.IsSuccess = false; result.FailureType = RunResultFailureType.CompilerErrors; result.CompilerErrors = validateCodeResult.Errors; } if (result.CompilerErrors == null) { result.CompilerErrors = new List <ValidationError> { ValidationError.CreateFromException(ex) }; } TryCleanRoslynCacheHack(); PermissionSet.RevertAssert(); return; } object execResult = null; try { this.OnStartingExecution(); PermissionSet.RevertAssert(); execResult = submission.Execute(); this.OnFinishedExecution(); } catch (ThreadAbortException) { throw; } catch (Exception ex) { result.IsSuccess = false; result.FailureType = RunResultFailureType.RunTimeException; result.RunTimeException = new ExceptionInfo(ex); } finally { result.ConsoleOutput = _consoleWriter.ToString().TrimEnd(); if (execResult != null) { result.ConsoleOutput += Environment.NewLine; result.ConsoleOutput += "[Return value]: " + execResult; } // don't need it as we modified Roslyn assemblies and made fix in them // TryCleanRoslynCacheHack(); } }