【摘 要】
要利用.NET语言(例如:c# vb.net)开发自己的脚本语言必须实现2步:
1.能够动态编译.NET 源代码
2.动态调用.NET组件
首先我们介绍下动态条用.NET组件 1.新建1个工程作为组件接口DynamicInterface 创建新的类: using System;
namespace DynamicInterface { public interface IDynamic { string getString(); } }
2.新建1个工程作为需要动态调用的组件DynamicClass 引用DynamicInterface 创建新的类: using System;
namespace DynamicCls { public class DynamicClass:DynamicInterface.IDynamic //实现接口 { public DynamicClass() { } #region IDynamic 成员
public string getString() { // TODO: 添加 DynamicClass.getString 实现 return "Hello World Huhong"; }
#endregion }
3.新建1个工程来动态调用DynamicClass using System; using System.Reflection;
using System.Threading;
namespace dynamicreference { class DynamicReference { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(string[] args) { string dllfilename=@"C:\DynamicClass.dll"; Thread.GetDomain().AssemblyLoad+=new AssemblyLoadEventHandler(DynamicReference_AssemblyLoad); Thread.GetDomain().AssemblyResolve+=new ResolveEventHandler(DynamicReference_AssemblyResolve); Assembly asm=System.Reflection.Assembly.LoadFile(dllfilename); Type type=asm.GetType("DynamicCls.DynamicClass",true); Object oh=Activator.CreateInstance(type); MethodInfo mi = type.GetMethod("getString"); Console.WriteLine(mi.Invoke(oh,null).ToString()); //利用反射机制运行 DynamicInterface.IDynamic id=(DynamicInterface.IDynamic)oh; //利用接口运行 Console.WriteLine(id.getString()); }
private static void DynamicReference_AssemblyLoad(object sender, AssemblyLoadEventArgs args) { Console.WriteLine("加载1个组件:"+args.LoadedAssembly.FullName ); }
private static Assembly DynamicReference_AssemblyResolve(object sender, ResolveEventArgs args) { Console.WriteLine("组件解析失败!"); return null; } } }
动态编译: using System; using System.IO; using System.Text; using Microsoft.CSharp;
namespace TestProject { public class DynamicCompile { private String _physicspath = @"D:\Project.Net\TestProject\DcCodeFile\";//文件夹的路径 private String _outputpath = @"D:\Project.Net\TestProject\bin";//输出文件的路径
private String[] _filelist; //文件列表 private String[] _cscode; //源码 private String[] _filename; //文件名 private String[] _import; //引用 private System.Collections.IDictionary configs = null;//编译属性参数配置
public DynamicCompile() {}
public CompilerError[] ExCompiler() { Fill_cscode(); Fill_import(); Fill_configs(); CompilerError[] ce= Compiler.Compile(_cscode,_filename, _outputpath,_import, configs); return ce; } private String[] Fill_filelist() { return System.IO.Directory.GetFiles(_physicspath,"*.cs"); } private void Fill_cscode() { _filelist= Fill_filelist(); _cscode=new String[_filelist.Length]; _filename=new String[_filelist.Length]; for(int i=0;i<_filelist.Length;i++) { String filepath= _filelist.GetValue(i).ToString();//获取文件路径 _cscode[i]= ReadCodeFile(filepath, Encoding.GetEncoding("utf-8")); _filename[i]= System.IO.Path.GetFileName(filepath); } } private void Fill_import() { _import=new String[10];//数组长度视引用文件数量 _import[0]=@"C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll"; _import[1]=@"C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Web.dll"; } private void Fill_configs() { configs=new System.Collections.Specialized.ListDictionary(); configs.Add("target","library"); } //读取cscode内容 private String ReadCodeFile(String path,Encoding encode) { String content=String.Empty; try { if (File.Exists(path)) { StreamReader sr=new StreamReader(path,encode); content=sr.ReadToEnd(); sr.Close(); } } catch(IOException ex) { Console.Write(ex.ToString()); } return content; } } }
|