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