• 一个极其简单的在线C#IDE例子(zz)


    五一时去朋友那, 他问了个小问题, 只要写几十行代码就可以很好的说明问题.可偏偏机子没装VS, 只好做罢.回来后想想, 要是有个在线的C#IDE就好了.于是上网查了下相关的资料,  整出来个简单的在线C#IDE.
          做这个,主要要解决两个问题, 一是如果将网页上文本框的代码编译并执行;二是如果将程序运行结果在网页上输出.
          第一个问题不难, .NET已经有现成的C#编译类CSharpCodeProvider(或是其它语言的),再使用CompilerParameters类做为编译参数,就可以很容易的实现.
          第二个问题, 举最简单情况, 就是将Console.Write方法输出的内容在网页上显示出来.这其实也很好办,只要在编译之前, 在输出语句做一个替换, 将输出的内容存到另一个地方.等运行结束后, 再从那个地方取出来就是了.
         代码实现如下:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace VSOnline.Framework
    {
        
    /// <summary>
        
    /// 自定义的输出类
        
    /// </summary>

        public class Consoler
        
    {
            
    //存储所有输出
            public static Dictionary<string, Consoler> Outputs getset; }

            
    static Consoler()
            
    {
                Outputs 
    = new Dictionary<string, Consoler>();
            }


            
    输出操作
        }

    }
    using System;
    using System.Reflection;
    using Microsoft.CSharp;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    namespace VSOnline.Framework
    {
        
    /// <summary>
        
    /// 代码执行类
        
    /// </summary>

        public class CodeRun
        
    {
            
    /// <summary>
            
    /// Framework版本,可选择v2.0, v3.0, v3.5
            
    /// </summary>

            private string CompilerVersion getset; }

            
    /// <summary>
            
    /// 构造函数
            
    /// </summary>
            
    /// <param name="compilerVersion">Framework版本,可选择v2.0, v3.0, v3.5</param>

            public CodeRun(string compilerVersion)
            
    {
                CompilerVersion 
    = compilerVersion;
            }


            
    /// <summary>
            
    /// 构造函数,默认为3.5版本
            
    /// </summary>

            public CodeRun()
            
    {
                CompilerVersion 
    = "v3.5";
            }


            
    /// <summary>
            
    /// 动态编译并执行代码
            
    /// </summary>
            
    /// <param name="code">代码</param>
            
    /// <returns>返回输出内容</returns>

            public List<string> Run(string code, string id, params string[] assemblies)
            
    {
                Consoler.Outputs.Add(id, 
    new Consoler());
                CompilerParameters compilerParams 
    = new CompilerParameters();
                
    //编译器选项设置
                compilerParams.CompilerOptions = "/target:library /optimize";
                
    //compilerParams.CompilerOptions += @" /lib:""C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\""";
                
    //编译时在内存输出
                compilerParams.GenerateInMemory = true;
                
    //生成调试信息
                compilerParams.IncludeDebugInformation = false;
                
    //添加相关的引用
                foreach (string assembly in assemblies)
                
    {
                    compilerParams.ReferencedAssemblies.Add(assembly);
                }

                compilerParams.ReferencedAssemblies.Add(
    "mscorlib.dll");
                compilerParams.ReferencedAssemblies.Add(
    "System.dll");
                
    if (this.CompilerVersion == "v3.5")
                
    {
                    compilerParams.ReferencedAssemblies.Add(
    "System.Core.dll");
                }


                
    string path = "";
                
    try
                
    {
                    path 
    = HttpContext.Current.Server.MapPath("/bin/");
                }

                
    catch { }

                compilerParams.ReferencedAssemblies.Add(path 
    + "VSOnline.Framework.dll");
                CSharpCodeProvider compiler 
    = new CSharpCodeProvider(new Dictionary<stringstring>() "CompilerVersion", CompilerVersion } });
                
    //编译
                code = code.Replace("Console.WriteLine"string.Format("VSOnline.Framework.Consoler.Outputs[\"{0}\"].WriteLine", id));
                code 
    = code.Replace("Console.Write"string.Format("VSOnline.Framework.Consoler.Outputs[\"{0}\"].Write", id));
                CompilerResults results 
    = compiler.CompileAssemblyFromSource(compilerParams, code);
                
    //错误
                if (results.Errors.HasErrors)
                
    {
                    
    foreach (CompilerError error in results.Errors)
                    
    {
                        Consoler.Outputs[id].Output.Add(error.ErrorText 
    + "\n");
                    }


                    
    return ReturnOutput(id);
                }

                
    //创建程序集
                Assembly asm = results.CompiledAssembly;
                
    //获取编译后的类型
                object mainClass = asm.CreateInstance("Program");
                Type mainClassType 
    = mainClass.GetType();
                
    //输出结果
                mainClassType.GetMethod("Main").Invoke(mainClass, null);

                
    return ReturnOutput(id);
            }


            
    private List<string> ReturnOutput(string id)
            
    {
                
    string[] output = new string[Consoler.Outputs[id].Output.Count];
                Consoler.Outputs[id].Output.CopyTo(output, 
    0);
                Consoler.Outputs.Remove(id);

                
    return output.ToList();
            }

        }

    }


         测试:

    using VSOnline.Framework;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using System.Collections.Generic;
    using System;
    using FastDev.Core;
    using System.Linq;

    namespace Test
    {
        [TestClass()]
        
    public class CodeRunTest
        
    {
            [TestMethod()]
            
    public void RunTest()
            
    {
                CodeRun target 
    = new CodeRun();

                
    string code = @"
    using System;

    public class Program
    {
        public static void Main()
        {
            for(int index = 1;index <= 3;index++)
            {
                Console.Write(index);
            }
        }
    }
                
    ";
                List
    <string> expected = new List<string>() "1""2""3" };
                List
    <string> actual;
                actual 
    = target.Run(code, "1");
                Assert.AreEqual(
    true, expected.SerializeEqual(actual));

                actual 
    = target.Run(code, "2");
                Assert.AreEqual(
    true, expected.SerializeEqual(actual));
            }


            [TestMethod()]
            
    public void Run35Test()
            
    {
                CodeRun target 
    = new CodeRun();

                
    string code = @"
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;

    public class Program
    {
        public static string Name { get; set; }

        public static void Main()
        {
            Name = ""3"";
            Console.Write(Name);
        }
    }
                
    ";
                List
    <string> actual;
                actual 
    = target.Run(code, "1""System.Core.dll");
                Assert.AreEqual(
    "3", actual[0]);
            }

        }

    }

     
    然后只要搬到Web上就可以了, 截图:



    完整程序下载 : VSOnline.rar


  • 相关阅读:
    RTTI机制
    QT 实现 QTabWidget 的多个Tab宽度之和 等于 TabWidget 的宽度
    安装QT
    给QT 程序的EXE文件添加图标
    OceanBase使用libeasy原理源码分析:服务器端
    libev 源码浅析
    [转载]CAP理论十二年回顾:"规则"变了
    replication 技术摘要
    函数调用和函数返回 栈变化情况
    The Secret To 10 Million Concurrent Connections The Kernel Is The Problem, Not The Solution
  • 原文地址:https://www.cnblogs.com/end/p/2327294.html
Copyright © 2020-2023  润新知