using System; using System.Reflection; using System.Text; using System.CodeDom.Compiler; using Microsoft.CSharp; namespace Namaah.NetSUUS.Tools.CLI { public class Shell { private StringBuilder _code = new StringBuilder(); ICodeCompiler compiler = new CSharpCodeProvider().CreateCompiler(); CompilerParameters parameters = new CompilerParameters(); public static void Main() { new Shell().Start(); } public Shell() { parameters.GenerateInMemory = true; parameters.ReferencedAssemblies.Add("System.dll"); } public void Start() { string cmd = ReadCmd(); while (cmd != null) { object obj = Run(cmd); if (obj != null) Console.WriteLine(obj); cmd = ReadCmd(); } } private static string ReadCmd() { Console.Write("shell> "); return Console.ReadLine(); } private object Run(string cmd) { string code; string returnline = null; bool haserrors = false; if (!cmd.StartsWith("return")) { returnline = "return null;"; } code = @" using System; public class Runner { public object Run() { " + _code.ToString() + cmd + returnline + @" } }"; CompilerResults compiled = compiler.CompileAssemblyFromSource(parameters, code); foreach (CompilerError e in compiled.Errors) { Console.WriteLine(e.ErrorText); if (!e.IsWarning) haserrors = true; } if (haserrors) return null; object obj = compiled.CompiledAssembly.CreateInstance("Runner"); object returned = compiled.CompiledAssembly.GetType("Runner") .InvokeMember( "Run", BindingFlags.InvokeMethod, null, obj, new object[] {} ); _code.Append(cmd); // All ok so include the line if (returnline == null) // A return call means end of the session _code = new StringBuilder(); return returned; } } }