using System; using System.Collections.Generic; using System.Text; using System.CodeDom.Compiler; using System.Reflection; using System.IO; using System.Xml.Serialization; using System.Xml; namespace snippeter { public class Compiler { private string name; private string[] usingDirectives = { "using System;", "using System.IO;", "using System.Text;", "using System.Diagnostics;", "using System.Collections;" }; public string Name { get { return name; } set { name = value; } } public string[] UsingDirectives { get { return usingDirectives; } set { usingDirectives = value; } } public Compiler() { } public Compiler(string name) { this.name = name; } private const string classHeader = @"public delegate void Proc(); public class Wrapper { public static object Set(string name, object value) { AppDomain.CurrentDomain.SetData(name, value); return value; } public static object Get(string name) { return AppDomain.CurrentDomain.GetData(name); } public static object Invoke(Proc proc) { proc(); return null; } public static string Eval() { StringWriter writer = new StringWriter(); Console.SetOut(writer);"; private const string classFooter = "return writer.ToString();}}"; public string Run(string text) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(string.Join("", usingDirectives)); stringBuilder.Append(classHeader); stringBuilder.Append(Environment.NewLine); stringBuilder.Append(text); stringBuilder.Append(Environment.NewLine); stringBuilder.Append(classFooter); string program = stringBuilder.ToString(); CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp"); CompilerParameters cp = new CompilerParameters(); cp.GenerateInMemory = true; cp.GenerateExecutable = false; Assembly executingAssembly = Assembly.GetExecutingAssembly(); cp.ReferencedAssemblies.Add(executingAssembly.Location); foreach (AssemblyName assemblyName in executingAssembly.GetReferencedAssemblies()) { cp.ReferencedAssemblies.Add(Assembly.Load(assemblyName).Location); } CompilerResults result = provider.CompileAssemblyFromSource(cp, program); if (result.Errors.HasErrors) { if (result.Errors[0].ErrorNumber == "CS0029") return Run("Invoke(delegate { " + text + "; })"); return result.Errors[0].ErrorText; } else { Assembly assembly = result.CompiledAssembly; Type target = assembly.GetType("Wrapper"); MethodInfo method = target.GetMethod("Eval"); object invoke = method.Invoke(null, null); return invoke == null ? null : invoke.ToString(); } } public void Serialize() { MemoryStream stream = new MemoryStream(); XmlSerializer serializer = new XmlSerializer(this.GetType()); XmlTextWriter xmlWriter = new XmlTextWriter(stream, Encoding.UTF8); xmlWriter.Formatting = Formatting.Indented; serializer.Serialize(xmlWriter, this); stream = (MemoryStream)xmlWriter.BaseStream; string str = Encoding.UTF8.GetString(stream.ToArray()); TextWriter writer = File.CreateText(name.ToLower() + ".xml"); writer.Write(str); writer.Close(); } public static Compiler Deserialize(string fullName) { XmlSerializer serializer = new XmlSerializer(typeof(Compiler)); TextReader reader = File.OpenText(fullName); MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(reader.ReadToEnd())); reader.Close(); XmlTextWriter xmlWriter = new XmlTextWriter(stream, Encoding.UTF8); return (Compiler)serializer.Deserialize(stream); } } }