有时候我们需要尝试动态地与一些代码进行交互,而不是只能执行程序内已编死的代码,那该怎么办呢?
我首先推荐各种脚本语言,如Javascript、Lua、Python等等,这些脚本语言有很多优秀的第三方类库,可以很方便的与 .NET 系统集成,让我们的程序中执行动态代码。

但如果你一定想用VB.NET或者C#的代码来运行一段程序,这里就要用到动态编译的功能了。

下面是我写的两个实例,你只需要在窗体 FormMain 中添加一个 button 和一个 textbox 即可,默认名为 Button1TextBox1

VB.NET代码

Imports System.CodeDom.Compiler
Imports System.Reflection

Public Class FormMain

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' 编译参数
        Dim cpars As New CompilerParameters

        ' 编译参数,如 /optimize /removeintchecks 等
        cpars.CompilerOptions = "/optimize "

        cpars.GenerateInMemory = True '在内存中编译而不输出文件
        cpars.GenerateExecutable = False '并不输出执行文件
        cpars.IncludeDebugInformation = False '不需要调试信息

        ' 导入类库(根据自己代码的需要导入)
        cpars.ReferencedAssemblies.Add("mscorlib.dll")
        cpars.ReferencedAssemblies.Add("System.dll")
        cpars.ReferencedAssemblies.Add("System.Data.dll")
        cpars.ReferencedAssemblies.Add("System.Deployment.dll")
        cpars.ReferencedAssemblies.Add("System.Drawing.dll")
        cpars.ReferencedAssemblies.Add("System.Windows.Forms.dll")
        cpars.ReferencedAssemblies.Add("System.Xml.dll")
        cpars.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")

        ' 编译参数,为导入的类库设置全局引用(否则必须使用完整的命名空间名称才能正确调用函数)
        cpars.CompilerOptions &= " /imports:" & _
         "Microsoft.VisualBasic," & _
         "System," & _
         "System.Collections," & _
         "System.Collections.Generic," & _
         "System.Drawing," & _
         "System.Windows.Forms"

        ' 设置编译器
        Dim vbc As New VBCodeProvider
        'Dim vbc = CodeDomProvider.CreateProvider("VisualBasic") '等效方法

        ' 一个简单的模板类
        Dim codex As String = _
         "Public Class CompClass" & vbCrLf & _
         "    Shared Function RunCode() As Object" & vbCrLf & _
         "        '$" & vbCrLf & _
         "    End Function" & vbCrLf & _
         "End Class"

        ' 替换代码到模板类中
        Dim code As String = codex.Replace("'$", TextBox1.Text)

        ' 编译并返回
        Dim resut As CompilerResults = vbc.CompileAssemblyFromSource(cpars, code)

        ' 如果发生了错误
         Then
            ).ToString)
            Return
        End If

        ' 尝试调用代码
        Dim asm As Assembly = resut.CompiledAssembly '获取程序集

        ' 获取我们编写的静态方法
        Dim mi As MethodInfo = asm.GetType("CompClass").GetMethod("RunCode")

        ' 执行代码,并获取返回值
        Dim ret As Object = mi.Invoke(Nothing, Nothing)

        ' 对返回值进行处理
        If ret IsNot Nothing Then
            MsgBox(ret.ToString)
        End If

    End Sub

End Class

执行程序,在 Textbox1 里写入一些VB代码,按 Button1 即可立即执行里面的代码。
如果拥有返回值,程序还可以获取代码的返回值,但有可能需要你进行拆箱处理。

C#代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Reflection;
using System.CodeDom.Compiler;

namespace WindowsFormsApplication1
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            // 编译参数
            var cpars = new CompilerParameters();
            cpars.CompilerOptions = "/optimize ";
            cpars.GenerateInMemory = true;
            cpars.GenerateExecutable = false;
            cpars.IncludeDebugInformation = false;

            // 导入类库(根据自己代码的需要导入)
            cpars.ReferencedAssemblies.Add("mscorlib.dll");
            cpars.ReferencedAssemblies.Add("System.dll");
            cpars.ReferencedAssemblies.Add("System.Data.dll");
            cpars.ReferencedAssemblies.Add("System.Deployment.dll");
            cpars.ReferencedAssemblies.Add("System.Drawing.dll");
            cpars.ReferencedAssemblies.Add("System.Windows.Forms.dll");
            cpars.ReferencedAssemblies.Add("System.Xml.dll");

            // 编译器实例
            var csc = new Microsoft.CSharp.CSharpCodeProvider();
            //var csc = CodeDomProvider.CreateProvider("CSharp");

            // 一个简单的模板类
            // 因为C#的编译器无法设置全局命名空间,所以需要在代码中导入命名空间
            var codex = @"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
class CompClass{
    static public object RunCode(){
        //$
        return null;
    }
}
";

            // 替换代码到模板类中
            var code = codex.Replace("//$", TextBox1.Text);

            // 编译并返回
            var resut = csc.CompileAssemblyFromSource(cpars, code);

            // 错误警告
            ) {
                MessageBox.Show(resut.Errors[].ToString());
                return;
            }

            // 调用代码
            var asm = resut.CompiledAssembly;
            var mi = asm.GetType("CompClass").GetMethod("RunCode");

            object ret = mi.Invoke(null, null);
            if (ret != null) {
                MessageBox.Show(ret.ToString());
            }
        }
    }
}

C#的代码流程与VB的基本相同,区别在于C#的编译器没有导入全局命名空间的参数,因此需要在模板类里写入你需要导入的命名空间。
其他的用法基本都一样。

PS: 我有空再写一点与第三方脚本库进行交互的代码示例。

动态执行 VB.NET 和 C# 代码的更多相关文章

  1. C#动态执行代码

          在开始之前,先熟悉几个类及部分属性.方法:CSharpCodeProvider.ICodeCompiler.CompilerParameters.CompilerResults.Assem ...

  2. (转+整理)C#中动态执行代码

    通过微软提供的CSharpCodeProvider,CompilerParameters,CompilerResults等类,可以在运行时,动态执行自己写的代码文件.原理就是把你的代码文件动态编译成e ...

  3. 动态执行文本vba代码

    动态执行文本vba代码 Public Sub StringExecute(s As String) Dim vbComp As Object Set vbComp = ThisWorkbook.VBP ...

  4. Javascript动态执行JS(new Function与eval比较)

    new Function与eval可以动态执行JS,只要把拼接好的JS方法,然后以字符串的形式传入到这两个函数,可以执行,其中new Function用在模板引擎比较多. 用 Function 类直接 ...

  5. PHP 动态执行

    PHP 动态执行 在页面上直接输入代码,点击执行,返回执行结果 方法很简单,主要使用了 $newfunc = create_function('', $code); 函数来实现. 代码如下: < ...

  6. JDK1.8中如何用ScriptEngine动态执行JS

    JDK1.8中如何用ScriptEngine动态执行JS jdk1.6开始就提供了动态脚本语言诸如JavaScript动态的支持.这无疑是一个很好的功能,毕竟Java的语法不是适合成为动态语言.而JD ...

  7. 【05】Firebug动态执行JavaScript

    Firebug动态执行JavaScript 您可以使用Firebug来编写并实时执行一个JavaScript. 这是为了测试,并确保该脚本工作正常,这是将JavaScript代码部署在生产环境前的好方 ...

  8. 根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案

    原文:根据数据库记录动态生成C#类及其公共属性并动态执行的解决方案 问题: C#中,想动态产生这么一个类: public class StatisticsData    {        public ...

  9. 第6.6节 Python动态执行小结

    一.    Python动态执行支持通过输入数据流或文件传入Python源代码串,进行编译后执行,可以通过这种方式扩展Python程序的功能: 二.    动态执行方法可能导致恶意攻击,因此使用时需要 ...

随机推荐

  1. xgboost安装

    安装连接:https://www.zhihu.com/question/46377605 软件连接:https://www.lfd.uci.edu/~gohlke/pythonlibs/#xgboos ...

  2. IntelliJ IDEA 配置svn

    1.启用版本控制 2.在弹出的框中选择svn 3.下载并解压VisualSVN  下载地址:http://subversion.apache.org/packages.html#windows 4.i ...

  3. 关于使用的xshll和xftp中乱码咋办?

    1.Xshll中 2.Xftp中同理都是一样的设置

  4. VMware 15 Pro密钥

    YG5H2-ANZ0H-M8ERY-TXZZZ-YKRV8 UG5J2-0ME12-M89WY-NPWXX-WQH88 UA5DR-2ZD4H-089FY-6YQ5T-YPRX6 GA590-86Y0 ...

  5. Flex 得到一个对象的所有属性

    var obj:Object =..... ///需要处理的对象 fieldname:Array = ObjectUtil.getClassInfo(obj)["properties&quo ...

  6. 关于Windows 8 合约

    浅谈win8合约: http://www.devdiv.com/Windows_Metro-windows_metro_app_windows_contracts_-thread-131717-1-1 ...

  7. windows mysql绿色版配置

    MySQL绿色版安装 1.下载地址 https://dev.mysql.com/downloads/mysql/ 2.配置my.ini 文件 解压下载文件到指定目录.如: my.ini文件内容: [m ...

  8. keras环境

    Windows 7 python3.6 在安装 Keras 之前, 需要确认自己已经安装好了 Numpy 和 Scipy. 安装个anaconda3就可以搞定 因为 Keras 是基于 Tensorf ...

  9. 2018.11.02 洛谷P3952 时间复杂度(模拟)

    传送门 惊叹考场dubuffdubuffdubuff. 这题还没有梭哈难啊233. 直接按照题意模拟就行了. 代码: #include<bits/stdc++.h> using names ...

  10. UVa 10294 Arif in Dhaka (First Love Part 2) (Polya定理)

    题意:给定 n 和 m 表示要制作一个项链和手镯,项链和手镯的区别就是手镯旋转和翻转都是相同的,而项链旋转都是相同的,而翻转是不同的,问你使用 n 个珠子和 m 种颜色可以制作多少种项链和手镯. 析: ...