Visual Studio for Application 内幕之二
当然,我们不会在每次都Compile,run,这样并不是我们的本意,利用IVsaSite接口的GetCompiledState,我们可以在编译后的pe文件和调试信息文件装入
Public Sub GetCompiledState(ByRef pe() As Byte, ByRef debugInfo() As Byte) Implements Microsoft.Vsa.IVsaSite.GetCompiledState
End Sub
这个过程的实现有两个参数,第一是pe文件的二进制表示,其二是debug信息,说白了第一个文件是dll的二进制值,第二个文件是pdb文件的二进制值
如何得到编译后的pe文件和调试信息文件
这个过程主要使用VsaEngine的SaveComiledState方法来实现,在正确Compile后
If m_VsaEngine.Compile() Then
m_VsaEngine.Run()
End If
Dim pe() As Byte
Dim pdb() As Byte
m_VsaEngine.SaveCompiledState(pe, pdb)
接下去,就是写二进制文件的问题了
Dim fs As New FileStream("c:\test.dll", FileMode.Create)
Dim bs As New BinaryWriter(fs)
bs.Write(pe)
fs.Close()
bs.Close()
fs = New FileStream("c:\test.pdb", FileMode.Create)
bs = New BinaryWriter(fs)
bs.Write(pdb)
fs.Close()
bs.Close()
接下来,我们切换到实现IVsaSite的类,在这个例子中是MyVsaSite,我们实现GetCompiledState方法
Public Sub GetCompiledState(ByRef pe() As Byte, ByRef debugInfo() As Byte) Implements Microsoft.Vsa.IVsaSite.GetCompiledState
Dim fs As FileStream = New FileStream("c:\test.dll", FileMode.Open)
Dim bs As BinaryReader = New BinaryReader(fs)
pe = bs.ReadBytes(fs.Length)
fs.Close()
bs.Close()
fs = New FileStream("c:\test.pdb", FileMode.Open)
bs = New BinaryReader(fs)
debugInfo = bs.ReadBytes(fs.Length)
End Sub
当调用VsaLoader的Run方法时,VsaLoader会调用其Site对象的GetCompiledState方法,获取数据
这是调用的例子
m_VsaEngine = New Microsoft.Vsa.VsaLoader
m_VsaEngine.RootNamespace = "test"
m_VsaEngine.RootMoniker = "test://project1"
m_VsaEngine.Site = New MyVsaSite
m_VsaEngine.Run()
Dim args() As Object = New Object() {"jjx"}
Invoke("TestClass.Hello", args)