在线C#IDE例子

  五一时去朋友那, 他问了个小问题, 只要写几十行代码就可以很好的说明问题.可偏偏机子没装VS, 只好做罢.回来后想想, 要是有个在线的C#IDE就好了.于是上网查了下相关的资料, 整出来个简单的在线C#IDE.

  做这个,主要要解决两个问题, 一是如果将网页上文本框的代码编译并执行;二是如果将程序运行结果在网页上输出.

  第一个问题不难, .NET已经有现成的C#编译类CSharpCodeProvider(或是其它语言的),再使用CompilerParameters类做为编译参数,就可以很容易的实现.

  第二个问题, 举最简单情况, 就是将Console.Write方法输出的内容在网页上显示出来.这其实也很好办,只要在编译之前, 在输出语句做一个替换, 将输出的内容存到另一个地方.等运行结束后, 再从那个地方取出来就是了.

  代码实现如下: 以下是引用片段:

 

  
  
  
  
  1. using System;  
  2.   using System.Collections.Generic;  
  3.   using System.Linq;  
  4.   using System.Text;  
  5.     
  6.   namespace VSOnline.Framework  
  7.   {  
  8.    /**////   
  9.    /// 自定义的输出类  
  10.    ///   
  11.    public class Consoler  
  12.    {  
  13.    //存储所有输出  
  14.    public static Dictionary Outputs { getset; }  
  15.     
  16.    static Consoler()  
  17.    {  
  18.    Outputs = new Dictionary();  
  19.    }  
  20.     
  21.    输出操作#region 输出操作  
  22.     
  23.    //当前输出  
  24.    public List Output { getprivate set; }  
  25.     
  26.    public Consoler()  
  27.    {  
  28.    Output = new List();  
  29.    }  
  30.     
  31.    public void Write(object str)  
  32.    {  
  33.    Output.Add(str.ToString());  
  34.    }  
  35.     
  36.    public void WriteLine(object str)  
  37.    {  
  38.    Output.Add(str.ToString() + "n");  
  39.    }  
  40.     
  41.    #endregion  
  42.    }  
  43.   }  
  44.   using System;  
  45.   using System.Reflection;  
  46.   using Microsoft.CSharp;  
  47.   using System.CodeDom.Compiler;  
  48.   using System.Collections.Generic;  
  49.   using System.Linq;  
  50.   using System.Web;  
  51.     
  52.   namespace VSOnline.Framework  
  53.   {  
  54.    /**////   
  55.    /// 代码执行类  
  56.    ///   
  57.    public class CodeRun  
  58.    {  
  59.    /**////   
  60.    /// Framework版本,可选择v2.0, v3.0, v3.5  
  61.    ///   
  62.    private string CompilerVersion { getset; }  
  63.     
  64.    /**////   
  65.    /// 构造函数  
  66.    ///   
  67.    /// Framework版本,可选择v2.0, v3.0, v3.5  
  68.    public CodeRun(string compilerVersion)  
  69.    {  
  70.    CompilerVersion = compilerVersion;  
  71.    }  
  72.     
  73.    /**////   
  74.    /// 构造函数,默认为3.5版本  
  75.    ///   
  76.    public CodeRun()  
  77.    {  
  78.    CompilerVersion = "v3.5";  
  79.    }  
  80.     
  81.    /**////   
  82.    /// 动态编译并执行代码  
  83.    ///   
  84.    /// 代码  
  85.    /// 返回输出内容  
  86.    public List Run(string code, string id, params string[] assemblies)  
  87.    {  
  88.    Consoler.Outputs.Add(id, new Consoler());  
  89.    CompilerParameters compilerParams = new CompilerParameters();  
  90.    //编译器选项设置  
  91.    compilerParams.CompilerOptions = "/target:library /optimize";  
  92.    //compilerParams.CompilerOptions += @" /lib:""C:Program FilesReference AssembliesMicrosoftFrameworkv3.5""";  
  93.    //编译时在内存输出  
  94.    compilerParams.GenerateInMemory = true;  
  95.    //生成调试信息  
  96.    compilerParams.IncludeDebugInformation = false;  
  97.    //添加相关的引用  
  98.    foreach (string assembly in assemblies)  
  99.    {  
  100.    compilerParams.ReferencedAssemblies.Add(assembly);  
  101.    }  
  102.    compilerParams.ReferencedAssemblies.Add("mscorlib.dll");  
  103.    compilerParams.ReferencedAssemblies.Add("System.dll");  
  104.    if (this.CompilerVersion == "v3.5")  
  105.    {  
  106.    compilerParams.ReferencedAssemblies.Add("System.Core.dll");  
  107.    }  
  108.     
  109.    string path = "";  
  110.    try 
  111.    {  
  112.    path = HttpContext.Current.Server.MapPath("/bin/");  
  113.    }  
  114.    catch { }  
  115.     
  116.    compilerParams.ReferencedAssemblies.Add(path + "VSOnline.Framework.dll");  
  117.    CSharpCodeProvider compiler = new CSharpCodeProvider(new Dictionary() { { "CompilerVersion", CompilerVersion } });  
  118.    //编译  
  119.    code = code.Replace("Console.WriteLine"string.Format("VSOnline.Framework.Consoler.Outputs["{0}"].WriteLine", id));  
  120.    code = code.Replace("Console.Write"string.Format("VSOnline.Framework.Consoler.Outputs["{0}"].Write", id));  
  121.    CompilerResults results = compiler.CompileAssemblyFromSource(compilerParams, code);  
  122.    //错误  
  123.    if (results.Errors.HasErrors)  
  124.    {  
  125.    foreach (CompilerError error in results.Errors)  
  126.    {  
  127.    Consoler.Outputs[id].Output.Add(error.ErrorText + "n");  
  128.    }  
  129.     
  130.    return ReturnOutput(id);  
  131.    }  
  132.    //创建程序集  
  133.    Assembly asm = results.CompiledAssembly;  
  134.    //获取编译后的类型  
  135.    object mainClass = asm.CreateInstance("Program");  
  136.    Type mainClassType = mainClass.GetType();  
  137.    //输出结果  
  138.    mainClassType.GetMethod("Main").Invoke(mainClass, null);  
  139.     
  140.    return ReturnOutput(id);  
  141.    }  
  142.     
  143.    private List ReturnOutput(string id)  
  144.    {  
  145.    string[] output = new string[Consoler.Outputs[id].Output.Count];  
  146.    Consoler.Outputs[id].Output.CopyTo(output, 0);  
  147.    Consoler.Outputs.Remove(id);  
  148.     
  149.    return output.ToList();  
  150.    }  
  151.    }  
  152.   }  

 测试:

  以下是引用片段:

 

  
  
  
  
  1. using VSOnline.Framework;  
  2.   using Microsoft.VisualStudio.TestTools.UnitTesting;  
  3.   using System.Collections.Generic;  
  4.   using System;  
  5.   using FastDev.Core;  
  6.   using System.Linq;  
  7.     
  8.   namespace Test  
  9.   {  
  10.    [TestClass()]  
  11.    public class CodeRunTest  
  12.    {  
  13.    [TestMethod()]  
  14.    public void RunTest()  
  15.    {  
  16.    CodeRun target = new CodeRun();  
  17.     
  18.    string code = @"  
  19.   using System;  
  20.     
  21.   public class Program  
  22.   {  
  23.    public static void Main()  
  24.    {  
  25.    for(int index = 1;index <= 3;index++)  
  26.    {  
  27.    Console.Write(index);  
  28.    }  
  29.    }  
  30.   }  
  31.    ";  
  32.    List expected = new List() { "1""2""3" };  
  33.    List actual;  
  34.    actual = target.Run(code, "1");  
  35.    Assert.AreEqual(true, expected.SerializeEqual(actual));  
  36.     
  37.    actual = target.Run(code, "2");  
  38.    Assert.AreEqual(true, expected.SerializeEqual(actual));  
  39.    }  
  40.     
  41.    [TestMethod()]  
  42.    public void Run35Test()  
  43.    {  
  44.    CodeRun target = new CodeRun();  
  45.     
  46.    string code = @"  
  47.   using System;  
  48.   using System.Collections;  
  49.   using System.Collections.Generic;  
  50.   using System.Linq;  
  51.     
  52.   public class Program  
  53.   {  
  54.    public static string Name { getset; }  
  55.     
  56.    public static void Main()  
  57.    {  
  58.    Name = ""3"";  
  59.    Console.Write(Name);  
  60.    }  
  61.   }  
  62.    ";  
  63.    List actual;  
  64.    actual = target.Run(code, "1""System.Core.dll");  
  65.    Assert.AreEqual("3", actual[0]);  
  66.    }  
  67.    }  
  68.   }  

 

你可能感兴趣的:(职场,休闲,在线C#IDE例子)