//引擎實現部分:
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 = roo
tMoniker;
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;
}
}
}