C#高级应用之Microsoft.Vsa引擎篇

//引擎实现部分:

 using System;
using System.Collections;
using System.IO;
using System.Reflection;
using Microsoft.VisualBasic.Vsa;
using Microsoft.Vsa;
//作者注:需要增加对Microsoft.Vsa.dll,Microsoft.VisualBasic.Vsa.dll,Microsoft.JScript.dll的引用
namespace ToolPackages
{
 public class ScriptControl
 {
  static ScriptControl()
  {
  
  }
  public void Close()
  {
   engine.Close();

  }
  private IVsaEngine engine;
  private String rootNamespace;
  private String rootMoniker;
  private ScriptControlSite site;  
  public IVsaError Error
  {
   get { return site.Error; }
  }
  public void Run()
  {
   if (!engine.IsRunning)
   {
    if (!engine.IsCompiled)
     engine.Compile();
    if (engine.IsCompiled == false)
    {
     String message = "Error on line " + Error.Line + ", col " + Error.EndColumn + "/r/n" + Error.LineText + "/r" + Error.Description;
     throw new Exception(message);

    }

    engine.Run();
   }
  }

  public void AddCode(String itemName, String code)
  {
   IVsaCodeItem item = GetCodeItem(itemName);
   item.AppendSourceText(code);
  }
  public ScriptControl(String rootNamespace) : this(rootNamespace, "SharpnessdotnetApp://SharpnessdotnetProject", "Microsoft.VisualBasic.Vsa.VsaEngine")
  {
  }

  public ScriptControl(String rootNamespace, String rootMoniker, String language)
  {
  
   this.rootNamespace = rootNamespace;
   this.rootMoniker = rootMoniker;
   switch (language.ToLower())
   {
    case "microsoft.visualbaisc.vsa":
     engine = new VsaEngine();
     break;
    case "microsoft.jscript.vsa":
     engine = new Microsoft.JScript.Vsa.VsaEngine();
     break;
    default:
     engine = new VsaEngine();
     break;

   }   
   site = new ScriptControlSite();
   engine.RootMoniker = rootMoniker;
   engine.Site = site;
   engine.InitNew();
   engine.RootNamespace = rootNamespace;

  }
  public void AddReference(String fullName)
  {
   AddReference(Assembly.Load(fullName));
  }
  public void AddReference(Type t)
  {
   AddReference(t.Assembly);
  }
  public void AddReference(Assembly asm)
  {
   
   try
   {
    IVsaReferenceItem item = (IVsaReferenceItem) engine.Items.CreateItem(asm.Location, VsaItemType.Reference, VsaItemFlag.None);

    item.AssemblyName = asm.Location;
   }
   catch(Microsoft.Vsa.VsaException exception)
   {
    string message = exception.Message;
   }


  }
  public void AddObject(String name, Object obj)
  {
   site.AddObject(name, obj);
   Type t = obj.GetType();
   if (!(engine is VsaLoader))
   {
    IVsaGlobalItem GlobalItem;
    GlobalItem = (IVsaGlobalItem) engine.Items.CreateItem(name, VsaItemType.AppGlobal, VsaItemFlag.None);

    GlobalItem.TypeString = t.FullName;
   }
  }
  public void AddEventSourceObject(String itemName, String name, Object obj)
  {
   if (!(engine is VsaLoader))
   {
    IVsaCodeItem codeItem;
    codeItem = GetCodeItem(itemName);

    if (codeItem.SourceText == null || codeItem.SourceText.Length == 0)
     throw new InvalidOperationException("no scripts to run");
    codeItem.AddEventSource(name, obj.GetType().FullName);

   }
   site.AddEventSourceObject(itemName, name, obj);
  }
  public object Invoke(string methodName, object[] arguments)
  {
   if ((null == methodName) || (0 == String.Compare(methodName, "")))
    throw new ArgumentNullException("methodName");
   if (false == engine.IsRunning)
    Run();
   char[] seprators = {'.'};
   string[] parts;
   parts = methodName.Split(seprators);
   if (parts.Length < 2)
    throw  new ArgumentNullException("methodName");
   int procNamePos = methodName.LastIndexOf('.');
   string typeName = methodName.Substring(0, procNamePos);
   string procName = methodName.Substring(procNamePos + 1);
   if (null == procName)
    throw  new ArgumentNullException("methodName");
   string RootNamespace;
   string Fullname;
   RootNamespace = engine.RootNamespace;
   Fullname = RootNamespace + "." + typeName;
   Type clsType = engine.Assembly.GetType(Fullname, true, true);
   MethodInfo method = clsType.GetMethod(procName);
   if (null == method)
    throw  new ArgumentNullException("methodName");
   return method.Invoke(null, arguments);
  }
  private IVsaCodeItem GetCodeItem(String itemName)
  {
   if (itemName == null || itemName.Length == 0)
    itemName = "Module1";
   IVsaCodeItem codeItem = null;
   try
   {
    codeItem = (IVsaCodeItem) engine.Items[itemName];
   }
   catch
   {
   }
   if (codeItem == null)
    codeItem = (IVsaCodeItem) engine.Items.CreateItem(itemName, VsaItemType.Code, VsaItemFlag.None);
   return codeItem;
  }
  private class ScriptControlSite : IVsaSite
  {
   private IDictionary hostObjects;
   private IDictionary eventSourceObjects;
   private byte[] pe = null;
   private byte[] pdb = null;
   public IVsaError Error;

   private byte[] Read(String filename)
   {
    FileStream fs = new FileStream(filename, FileMode.Open);
    BinaryReader br = new BinaryReader(fs);
    return br.ReadBytes((int) fs.Length);
   }

   public void LoadFrom(String pefile, String pdbfile)
   {
    pe = Read(pefile);
    pdb = Read(pdbfile);
   }

   public ScriptControlSite()
   {
    this.hostObjects = new Hashtable();
    this.eventSourceObjects = new Hashtable();
   }

   public void AddObject(String name, Object obj)
   {
    this.hostObjects.Add(name, obj);

   }

   public void AddEventSourceObject(String itemName, String name, Object obj)
   {
    IDictionary eventSource;
    if (!eventSourceObjects.Contains(itemName))
    {
     eventSourceObjects.Add(itemName, new Hashtable());

    }
    eventSource = (IDictionary) eventSourceObjects[itemName];
    eventSource.Add(name, obj);
   }

   #region IVsaSite Members

   public object GetEventSourceInstance(string itemName, string eventSourceName)
   {
    IDictionary eventSoruce = (IDictionary) eventSourceObjects[itemName];
    return eventSoruce[eventSourceName];
   }

   public object GetGlobalInstance(string name)
   {
    return hostObjects[name];
   }

   public void Notify(string notify, object info)
   {
   }

   public bool OnCompilerError(IVsaError error)
   {
    Error = error;

    return false;
   }

   public void GetCompiledState(out byte[] pe, out byte[] debugInfo)
   {
    pe = this.pe;
    debugInfo = this.pdb;
   }

   #endregion
  }
 }
}

//调用演示部分:

using System;
using System.Threading;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Collections;
using System.Text;
//作者注:需要增加对Microsoft.Vsa.dll,Microsoft.VisualBasic.Vsa.dll,Microsoft.JScript.dll的引用
namespace ToolPackages
{
 public class SayHelloClass
 {
  public void Test()
  {
   Console.WriteLine("hello world.");
  }
 }
 public class VasShareExample
 {
  protected static String JSTEMPLATE = @"
   import System;
   import System.Collections;
   {imports}
   public class module1{
   static function execute()
   {
    {0}
   }
   }
   
  ";
  static void VasTest(string sTargetJscript,string importNamespaces)
  {
   //全局对象定义
   IDictionary objects = new Hashtable();
   objects.Add("globalVars","global var test in vsa");   
   string language = "Microsoft.JScript.Vsa";
   ScriptControl control = new ScriptControl("Sharpnessdotnet.vsa","myapp://myproject/"+Guid.NewGuid().ToString(),language);
   ///增加对程序集的引用
   Assembly assem = Assembly.GetExecutingAssembly();   
   control.AddReference(assem);   
   //增加 System
   control.AddReference(typeof(Console));
   //增加其它在脚本中要被引用的类型
   //control.AddReference(typeof(AnyType)); 
   //增加全局对象   
   foreach(String key in objects.Keys)
   {
    if (objects[key]!= null)
      control.AddObject(key,objects[key]);
   }   
   StringBuilder sb = new StringBuilder();
   //替换模板代码
   sb.Append(JSTEMPLATE.Replace("{0}",sTargetJscript).Replace("{imports}",importNamespaces));
   control.AddCode("module1",sb.ToString());  
   try
   {
    control.Run();   
   }
   catch (Exception e)
   {
    throw new Exception("Could not load scripting engine for VSA language: " + language, e);
   }
   try
   {
    control.Invoke("module1.execute",new object[]{});
   }
   catch (Exception e)
   {
    throw new Exception("VSA script/function could not run", e);
   }
   finally
   {
    control.Close();
   }
  }
  static void Main()
  {
   
   string targetScript = @"
   var message = 'run in script with vsa';
   try
   { 
    Console.WriteLine('成功进入Vsa应用世界...');
                Console.WriteLine('以下输出的是对一个公开类的公开静态方法的调用:');
    VasShareExample.Write(message);
    var a = 1;
    var b = 2;
                var c = 1 + 2;
                Console.WriteLine('以下输出的是全局变量[globalVars]的值:');   
    Console.WriteLine(globalVars);
    Console.WriteLine('以下输出的是简单计算[1 + 2]的值:'); 
    Console.WriteLine(c);
                Console.WriteLine('以下输出的是对一个公开类的公开实例方法的调用:');
    var sayHello = new SayHelloClass();
    sayHello.Test();
                Console.WriteLine('请输入字符串:');
    var input = Console.ReadLine();
    Console.WriteLine('您输入的字符串是:');
    Console.WriteLine(input);
                Console.WriteLine('开始进行应用程序跳转:');
    VasShareExample.Skip1(); 
   } 
   catch(e)
   {
    Console.WriteLine(e);
   }    
   ";
   string targetNamespace = "import ToolPackages; /r/n";   
   VasTest(targetScript,targetNamespace);
   Console.WriteLine("已从Vsa调用返回到宿主应用程序中,再见~");
   Console.ReadLine();
  }
  static void CheckFormat()
  {
   bool result = Test("",@"[^/s]{1,}$");
   Console.WriteLine(result.ToString());
  }
  public static void Skip1()
  {
   Console.WriteLine("已成功跳转到Skip1方法,本方法将立即跳转到Skip2方法");
   Skip2();
  }
  public static void Skip2()
  {
   Console.WriteLine("已成功跳转到Skip2方法,本方法将立即跳转到Skip3方法");
   Skip3();
  }
  public static void Skip3()
  {
   Console.WriteLine("已成功跳转到Skip3方法,本方法试图强制进行应用程序退出");
   Console.WriteLine(Thread.CurrentThread.ThreadState.ToString());
   Thread.CurrentThread.Interrupt();
  }
  public static void Write(string message)
  {
   Console.WriteLine(message);
  }
  static bool Test(string curValue,string format)
  {
   return Regex.Match(curValue, format).Success;
  }
 }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值