如何以编程方式编译使用 C# 编译器代码

c#中要运行文本文件中的c#代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;

using System.Reflection;
using System.Globalization;
using Microsoft.CSharp;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Text; 

using System.Windows.Forms;

namespace Test
{
    public partial class Form9 : Form
    {
        public Form9()
        {
            InitializeComponent();
        }
        void Run()
        {
            // 1.CodeComplier
            CodeDomProvider objICodeCompiler = CodeDomProvider.CreateProvider("CSharp");

            // 2.CompilerParameters 添加多个引用
            CompilerParameters objCompilerParameters = new CompilerParameters();
            objCompilerParameters.ReferencedAssemblies.Add("System.dll");
            objCompilerParameters.GenerateExecutable = false;
            objCompilerParameters.GenerateInMemory = true;

            // 3.CompilerResults
            CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, GenerateCode());

            if (cr.Errors.HasErrors)
            {
                Console.WriteLine("编译错误:");
                foreach (CompilerError err in cr.Errors)
                {
                    Console.WriteLine(err.ErrorText);
                }
            }
            else
            {
                // 通过反射,调用HelloWorld的实例
                Assembly objAssembly = cr.CompiledAssembly;
                object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.HelloWorld");
                MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut");

                MessageBox.Show(Convert.ToString(objMI.Invoke(objHelloWorld, null)));
            }         
        }

        static string GenerateCode()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("using System;");
            sb.Append(Environment.NewLine);
            sb.Append("namespace DynamicCodeGenerate");
            sb.Append(Environment.NewLine);
            sb.Append("{");
            sb.Append(Environment.NewLine);
            sb.Append(" public class HelloWorld");
            sb.Append(Environment.NewLine);
            sb.Append(" {");
            sb.Append(Environment.NewLine);
            sb.Append(" public string OutPut()");
            sb.Append(Environment.NewLine);
            sb.Append(" {");
            sb.Append(Environment.NewLine);
            sb.Append(" return \"Hello world!\";");
            sb.Append(Environment.NewLine);
            sb.Append(" }");
            sb.Append(Environment.NewLine);
            sb.Append(" }");
            sb.Append(Environment.NewLine);
            sb.Append("}");

            string code = sb.ToString();
            Console.WriteLine(code);
            Console.WriteLine();

            return code;
        }

        private void Form9_Load(object sender, EventArgs e)
        {
            Run();
        }
    }
}

 

以下是msdn上的文章,原文(http://support.microsoft.com/kb/304655

步骤 1: 要求

  • visual Studio
  • visual C# 语言编译器


 

第 2 步: 如何以编程方式编译代码

.NET Framework 提供了 ICodeCompiler 编译器执行接口。CSharpCodeProvider 类实现此接口,并提供对 C# 代码生成器和代码编译器的实例的访问。下面的代码示例创建 CSharpCodeProvider 的实例,并使用它来获取对 ICodeCompiler 接口的引用。

CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();
				


在您有了对 ICodeCompiler 接口的引用后可以使用它来编译源代码。 您将通过使用 CompilerParameters 类将参数传递给编译器。 下面是一个示例:

System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = icc.CompileAssemblyFromSource(parameters,SourceString);
				


上面的代码使用 CompilerParameters 对象告诉的编译器您要生成的可执行文件 (相对于 DLL) 和要输出到磁盘生成的程序集。 在调用 CompileAssemblyFromSource 是获取编译程序集的位置。 此方法将参数对象,并在源代码是字符串。 编译代码后,您可以检查是否有任何编译错误,请参阅。 使用从 CompileAssemblyFromSource,即 CompilerResults 对象返回的值。 此对象包含包含在编译过程中出现的所有错误的一个错误集合集合。

   if (results.Errors.Count > 0)
   {
    foreach(CompilerError CompErr in results.Errors)
    {
     textBox2.Text = textBox2.Text +
         "Line number " + CompErr.Line + 
         ", Error Number: " + CompErr.ErrorNumber + 
         ", '" + CompErr.ErrorText + ";" + 
         Environment.NewLine + Environment.NewLine;
    }
   }
				


 

步骤 3: 分步过程示例

  1. 创建一个新的 Visual C#.net Windows 应用程序。 默认情况下创建 Form1。
  2. 将一个 按钮 控件添加到 Form1,然后将其 文本 属性更改为 生成
  3. 将另一个 按钮 控件添加到 Form1,然后 运行 更改其 Text 属性。
  4. 向 Form1 中添加两个 文本框 控件,将这两个控件的 多行属性 设置为 True,然后大小这些控件,以便使您可以将多行文本粘贴到每个。
  5. 在代码编辑器中打开 Form1.cs 源文件。
  6. Form1 类粘贴下面的按钮单击处理程序。
    private void button1_Click(object sender, System.EventArgs e)
    {
        CSharpCodeProvider codeProvider = new CSharpCodeProvider();
        ICodeCompiler icc = codeProvider.CreateCompiler();
        string Output = "Out.exe";
        Button ButtonObject = (Button)sender;
    
        textBox2.Text = "";
        System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
        //Make sure we generate an EXE, not a DLL
        parameters.GenerateExecutable = true;
        parameters.OutputAssembly = Output;
        CompilerResults results = icc.CompileAssemblyFromSource(parameters, textBox1.Text);
    
        if (results.Errors.Count > 0)
        {
            textBox2.ForeColor = Color.Red;
            foreach (CompilerError CompErr in results.Errors)
            {
                textBox2.Text = textBox2.Text +
                            "Line number " + CompErr.Line +
                            ", Error Number: " + CompErr.ErrorNumber +
                            ", '" + CompErr.ErrorText + ";" +
                            Environment.NewLine + Environment.NewLine;
            }
        }
        else
        {
            //Successful Compile
            textBox2.ForeColor = Color.Blue;
            textBox2.Text = "Success!";
            //If we clicked run then launch our EXE
            if (ButtonObject.Text == "Run") Process.Start(Output);
        }
    }
    Add the beginning of the file, add these using statements:
    using System.CodeDom.Compiler;
    using System.Diagnostics;
    using Microsoft.CSharp;
    
    注意 如果您正在使用 Visual Studio 2005 或 Visual Studio 2008,CSharpCodeProvider 类已被否决。您可以改用 CodeDomProvider 类,如以下 button1_Click 实施所示。
    private void button1_Click(object sender, System.EventArgs e)
    {
        CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
        string Output = "Out.exe";
        Button ButtonObject = (Button)sender;
    
        textBox2.Text = "";
        System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
        //Make sure we generate an EXE, not a DLL
        parameters.GenerateExecutable = true;
        parameters.OutputAssembly = Output;
        CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, textBox1.Text);
    
        if (results.Errors.Count > 0)
        {
            textBox2.ForeColor = Color.Red;
            foreach (CompilerError CompErr in results.Errors)
            {
                textBox2.Text = textBox2.Text +
                            "Line number " + CompErr.Line +
                            ", Error Number: " + CompErr.ErrorNumber +
                            ", '" + CompErr.ErrorText + ";" +
                            Environment.NewLine + Environment.NewLine;
            }
        }
        else
        {
            //Successful Compile
            textBox2.ForeColor = Color.Blue;
            textBox2.Text = "Success!";
            //If we clicked run then launch our EXE
            if (ButtonObject.Text == "Run") Process.Start(Output);
        }
    }
    Add the beginning of the file, add these using statements:
    using System.CodeDom.Compiler;
    using System.Diagnostics;
    
  7. 在 Form1.cs,找到 Form1 构造函数。
  8. 在 Form1 构造函数中的调用 InitializeComponent 添加后下面的代码以线按钮单击添加到 Form1 的两个按钮的处理程序。
    public Form1()
    {
        InitializeComponent();
        this.button1.Click += new System.EventHandler(this.button1_Click);
        this.button2.Click += new System.EventHandler(this.button1_Click);
    }
    
  9. 运行该项目。 Form1 加载后,单击 生成器 按钮。 请注意您得到一个编译器错误。
  10. 接下来,将以下文本复制到文本框替换任何现有的文本:
    using System;
    
    namespace HelloWorld
    {
    	/// <summary>
    	/// Summary description for Class1.
    	/// </summary>
    	class HelloWorldClass
    	{
    		static void Main(string[] args)
    		{
    			Console.WriteLine("Hello World!");
    			Console.ReadLine();
    		}
    	}
    }
    					
  11. 再次单击 生成器。 编译应成功。
  12. 单击 运行,,它将编译代码并运行所生成的可执行文件。 编译将创建一个称为"Out.exe",保存您所运行的应用程序所在的文件夹中的可执行文件。

    注:您可以修改在文本框中以查看不同的编译器错误代码。 例如对于该分号之一删除并重新生成代码。
  13. 最后,修改代码,在文本框中输出到控制台窗口的文本的另一条直线。 单击 $ 运行 以查看输出。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值