Visual Studio for Application 内幕之一
关于vsa 的文档资料非常少,这也是我决定写一些介绍些文字的目的。当然,这里只是我对vsa的一些理解,可能有错误的地方,同时,也可能不适合初学者。
由于内容很多,计划分多次介绍
- 概述
- 装入预编译代码
- HostObject
- Vsa IDE
- Vsa sdk 部分(可能分多次)
在最前面的讲述中,我们不使用vsa sdk ,实际上,不用vsa sdk也可以实现所有的功能,在后面,我们详细介绍Vsa sdk(主要以beta 2为例,当然,我也打算介绍无意中发现的Vs.net 2003的vsa sdk版本)
相关命名空间
首先,我们来查看关于vsa的命名空间,发现有
Microsoft.Vsa(Microsoft.Vsa.Dll)
Microsoft.VisualBasic.Vsa(Microsoft.VisualBasic.Vsa.Dll)
Microsoft.JScript.Vsa(Microsoft.JScript.Vsa.Dll)
Microsoft_VsaVb(Microsoft_VsaVb.dll)
等
刚涉及vsa的开发者,很难理清其内在关系。我的理解是
vsa的功能实际上由基于com的实现完成,vsavbdt.dll是vsa设计时,而vsavb7rt.dll则是vsa运行时
Microsoft.Vsa 定义了基本的接口,枚举,异常
这里面重要的是VsaLoader类
VsaLoader主要用于装载和执行预先编译的vsa代码,只实现部分IVsaEngine接口,执行起来非常的快,在第二部分我们会介绍如何使用VsaLoader来装载预编译的Vsa代码
Microsoft_VsaVb是com实现的.net包装,查看Microsoft_VsaVB的代码,会发现其主要使用ComImportAttribute,Microsoft_VsaVB定义了VsaDTEngine接口(实现IVsaDTEngine接口),VsaDTEngineClass类(实现VsaDTEngine接口),VsaEngine接口(实现IVsaEngine接口),VsaEngineClass(实现VsaEngine接口)
而Visualbasic.Vsa和Microsoft.JScript.Vsa则分别是vb.net和JScript的具体实现
理解site 的概念
site相当于场所,VsaEgnine有IVsaSite的接口属性Site,其意义是我们需要创建一个实现IVsaSite接口的类,接受从VsaEngine引发的,如Notify,OnCompilerError,向实现IVsaEngine接口的对象提供值,如GetCompiledState,GetGlobalInstance等
IVsaSite非常重要,在以后我们会谈到
如:
读取预编译的代码
hostobject等
创建一个实现IVsaSite的类
imports Microsoft.vsa
class MyVsaSite
implements IVsaSite
.....
end class
任务场景:使用Microsoft.VisualBasic.vsa.VsaEngine 动态装入一个vb.net Class并运行
这是一个最通常的任务
在这个例子中,Textbox1中有一个class的代码,其代码如下
class TestClass
public shared sub Hello(byval name as string)
System.Windows.Forms.MessageBox.Show(name)
end sub
End Class
1、引用Microsoft.Vsa.dll,Microsoft.VisualBasic.vsa.dll
2、
imports Microsoft.Vsa
Imports Microsoft.VisualBasic.Vsa
3、在模块级定义IVsaEngine 变量
dim m_VsaEngine as IVsaEngine
4、创建Microsoft.VisualBasic.Vsa.VsaEngine的一个实例
m_VsaEngine=new Microsoft.VisualBasic.Vsa.VsaEngine()
5、 设置RootNameSpace和RootMoniker
m_VsaEngine.RootNameSpace="Test"
m_VsaEngine.RootMoniker="myapp://Project1"
6、设置Site属性(注:site必须在RootMoniker后设置)
m_VsaEngine.Site=new MyVsaSite
7、创建一个IVsaCodeItem实例
Dim codeItem As VsaCodeItem
codeItem = m_VsaEngine.Items.CreateItem("test", Microsoft.Vsa.VsaItemType.Code, Microsoft.Vsa.VsaItemFlag.Class)
codeItem.AppendSourceText(TextBox1.Text)
8、编译并运行
If m_VsaEngine.Compile() Then
m_VsaEnigne.Run()
End If
9、调用是通过Reflection进行的,为了简化这个调用过程,我用vb.net模拟了vsa sdk中的Runtime类Invoke的过程
Dim args() As Object = New Object() {"jjx"}
Invoke("TestClass.Hello", args)
Invoke 的vb.net实现
Public Overloads Function Invoke(ByVal methodName As String, ByVal arguments() As Object) As Object
If methodName Is Nothing OrElse String.Compare(methodName, "") = 0 Then
Throw New ArgumentNullException("methodName")
End If
If v Is Nothing Then
End If
If Not m_VsaEngine.IsRunning Then
m_VsaEngine.Run()
End If
Dim chs2() As Char = New Char() {"."}
If methodName.Split(chs2).Length < 2 Then
Throw New Exception("")
End If
Dim i As Integer = methodName.LastIndexOf(".")
Dim str1 As String = methodName.Substring(0, i)
Dim str2 As String = methodName.Substring(i + 1)
Dim str4 = String.Concat(ScriptEngine.RootNamespace, ".", str1)
Dim methodInfo As MethodInfo = ScriptEngine.Assembly.GetType(str4, True, True).GetMethod(str2)
If Not methodInfo Is Nothing Then
Return methodInfo.Invoke(Nothing, arguments)
End If
End Function
编译错误
通过实现IVsaSite接口的OnCompilerError可以了解编译错误信息
Public Function OnCompilerError(ByVal [error] As Microsoft.Vsa.IVsaError) As Boolean Implements Microsoft.Vsa.IVsaSite.OnCompilerError
Debug.WriteLine([error].Description)
End Function
引致:http://www.soho-works.net/blog/post/464.html