using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using Microsoft.CSharp;
namespace CSharpScript
{
public partial class formMain : Form
{
public formMain()
{
InitializeComponent();
this.txtInput.Text = @"using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace MyApplication
{
public class TestClass
{
static void Main(string[] args)
{
var str = ""www.haolizi.net 好例子网"";
Console.WriteLine(str);
}
}
}";
}
private void btnCompile_Click(object sender, EventArgs e)
{
string program=this.txtInput.Text;
string output="";
new Runner().CompileAndRun(program, out output);
this.txtOutPut.Text = output;
}
}
//public class CompileUtils
//{
// public static bool CanCompile(string program)
// {
// return !Compile(program).Errors.HasErrors;
// }
// public static CompilerResults Compile(string program)
// {
// CompilerResults compilerResults = null;
// System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
// parameters.WarningLevel = 4;
// parameters.ReferencedAssemblies.Add("System.dll");
// parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
// //#if CompileIntoMemory
// parameters.GenerateInMemory = true;
// //new CompilerParameters(new string[]
// // {
// // "System.dll"
// // })
// using (CSharpCodeProvider provider = new CSharpCodeProvider())
// {
// compilerResults = provider.CompileAssemblyFromSource(parameters,
// new string[] { program });
// }
// return compilerResults;
// }
//}
//public class PhoenixWriter : System.IO.TextWriter
//{
// delegate void VoidAction();
// System.Windows.Forms.TextBox txtBox;
// public PhoenixWriter(System.Windows.Forms.TextBox box)
// {
// this.txtBox = box;
// }
// public override System.Text.Encoding Encoding
// {
// get { return System.Text.Encoding.UTF8; }
// }
// //here, must use parameter: char value
// public override void Write(char value)
// {
// VoidAction action = delegate
// {
// txtBox.AppendText(value.ToString());
// };
// txtBox.BeginInvoke(action);
// }
//}
public class Runner
{
private static readonly string[] ConsoleAssemblyNames = new[]
{
"mscorlib.dll", "Microsoft.CSharp.dll",
"System.dll", "System.Core.dll",
"System.Data.dll", "System.Data.DataSetExtensions.dll",
"System.Xml.dll", "System.Xml.Linq.dll",
};
private static readonly Dictionary<string, string> CSharpCodeProviderOptions = new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } };
public bool CompileAndRun(string code, out string output)
{
var compiled = Compile(code);
if (compiled.Errors.HasErrors)
{
output = ReturnErrors(compiled);
return false;
}
output = ReturnOutput(compiled);
return true;
}
private static string ReturnErrors(CompilerResults compiled)
{
var builder = new StringBuilder();
builder.AppendLine("Compilation errors:");
compiled.Errors.Cast<CompilerError>()
.Select(ce => ce.ErrorText)
.ToList()
.ForEach(error => builder.AppendLine(error));
return builder.ToString();
}
private static CompilerResults Compile(string code)
{
using (var csc = new CSharpCodeProvider(CSharpCodeProviderOptions))
{
var parameters = new CompilerParameters(ConsoleAssemblyNames) { IncludeDebugInformation = true, GenerateInMemory = true };
var results = csc.CompileAssemblyFromSource(parameters, code);
return results;
}
}
private static string ReturnOutput(CompilerResults compiled)
{
using (var writer = new StringWriter())
{
Console.SetOut(writer);
//Console.SetIn(new StringReader(""));
var assembly = compiled.CompiledAssembly;
Type mainType = assembly.GetTypes().First(x => x.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Count(m => m.Name.ToLower() == "main") > 0);
var main = mainType.GetMethod("Main", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var postedParams = new object[] { new string[]{} };
main.Invoke(null, postedParams);
return writer.ToString();
}
}
}
}