【发布时间】:2017-02-23 16:36:31
【问题描述】:
我正在尝试为我的 VB .Net 应用程序创建一个应用程序脚本环境。我在应用程序中有一个名为 Project 的表单类型。我想要做的是在 Project 表单上动态编译(即 Eval)VB .Net 代码。此动态代码始终具有 Main 函数。 Main 的参数之一是对调用 Project 表单的引用。这是评估代码:
Public Function Eval(ByVal vbCode As String, ByRef MyAssembly As System.Reflection.Assembly, ByRef ProjectForm As Project) As ArrayList
Dim Provider As VBCodeProvider = CodeDomProvider.CreateProvider("VisualBasic")
Dim CompParams As CompilerParameters = New CompilerParameters
Dim CResult As CompilerResults
Dim EvalAssy As System.Reflection.Assembly
Dim InstanceObject As Object
Dim InstanceType As Type
Dim InstanceMI As MethodInfo
Dim CompError As CompilerError
Dim NumberOfErrors As Integer = 0
Dim ReturnValues As New ArrayList
Dim SkipAssembly As Boolean = False
Dim DebugTextBox As TextBox = ProjectForm.CompilationErrors
Dim DebugFilename As String = ProjectForm.DebugFile
Dim StatusBar As ToolStripStatusLabel = ProjectForm.MyMainForm.MessageToolStripStatusLabel
'Result = MsgBox("HMMM: " & CodeDomProvider.IsDefinedLanguage("VisualBasic").ToString(), MsgBoxStyle.OkOnly + MsgBoxStyle.Exclamation, "HMMM")
If Not DebugTextBox Is Nothing Then
DebugTextBox.Text &= "Running Eval On Assembly """ & MyAssembly.FullName & """." & vbCrLf
End If
CompParams.ReferencedAssemblies.Add("system.dll")
CompParams.ReferencedAssemblies.Add("system.xml.dll")
CompParams.ReferencedAssemblies.Add("system.data.dll")
CompParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
' Pass Myself In
CompParams.ReferencedAssemblies.Add(System.Reflection.Assembly.GetExecutingAssembly.Location)
CompParams.CompilerOptions = "/t:library"
CompParams.GenerateInMemory = True
CResult = Provider.CompileAssemblyFromSource(CompParams, vbCode)
For Each CompError In CResult.Errors
If Not CompError.IsWarning Then
' "Real Error"
NumberOfErrors += 1
End If
ReturnValues.Add("Error " & CompError.ErrorNumber & " On Line " & CompError.Line & ": " & CompError.ErrorText)
Next
If NumberOfErrors = 0 Then
Try
EvalAssy = CResult.CompiledAssembly
InstanceObject = EvalAssy.CreateInstance("Translation")
InstanceType = InstanceObject.GetType()
InstanceMI = InstanceType.GetMethod("Main")
InstanceMI.Invoke(InstanceObject, New Object() {MyAssembly, ProjectForm})
'InstanceMI.Invoke(InstanceObject, BindingFlags.Default, Nothing, New Object() {MyAssembly, ProjectForm}, System.Globalization.CultureInfo.CurrentCulture)
Catch Ex As Exception
If Ex.InnerException Is Nothing Then
WriteDebugMsg(DebugTextBox, "Error Evaling Compiled Code. The Error Is """ & Ex.Message)
Else
WriteDebugMsg(DebugTextBox, "Error Evaling Compiled Code. The Error Is:" & vbCrLf & Ex.Message & vbCrLf & "Inner Exception Is:" & vbCrLf & Ex.InnerException.ToString)
End If
End Try
End If
Return ReturnValues
End Function
动态(Eval)代码中的Main函数为:
Imports System
Imports System.Xml
Imports System.Data
Imports Microsoft.VisualBasic
Imports System.Reflection
Imports System.Diagnostics
Imports System.IO
Imports System.Windows.Forms
Imports System.Collections
Imports System.Text
Imports UniversalTranslator
Public Sub Main(ByRef MyAssembly As System.Reflection.Assembly, ByRef MyProjectForm As Project)
' Create functions needed to parse assembly here and in subroutines called from here
Me.ProjectForm = MyProjectForm
DebugFile = ProjectForm.DebugFile ' Set Global Debug Filename Variable
DebugTB = ProjectForm.CompilationErrors
' Initialize Log Files And Debug Textboxes
If Dir(DebugFile,FileAttribute.Normal) > "" Then
Kill(DebugFile)
End If
If Not DebugTB is Nothing Then
DebugTB.Text = ""
end if
RecurseAssemblyForms(MyAssembly,AddressOf OutputControlInfo)
End Sub
一切都在编译。编译后的代码将 MyProjectForm 识别为来自调用程序集的类型 Project。但是,当引用调用程序集项目表单执行代码时,出现以下错误:
在程序集“LaserTrak V4 软件,版本=4.507.3992.19399,文化=中性,PublicKeyToken=null”上运行评估。 评估编译代码时出错。错误是: 调用的目标已引发异常。 内部异常是: System.MissingMemberException:未找到类型“Project”的公共成员“CompilationErrors”。 在 Microsoft.VisualBasic.CompilerServices.Symbols.Container.GetMembers(String& MemberName, Boolean ReportErrors) 在 Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(对象实例,类型类型,字符串成员名称,对象 [] 参数,字符串 [] 参数名称,类型 [] 类型参数,布尔 [] CopyBack) 在 Translation.Main(Assembly& MyAssembly, Project& MyProjectForm)
我的猜测是 Main 过程没有对调用程序集活动 Project 表单的“可信”访问。我如何给它访问权限? 谢谢你的帮助。
【问题讨论】:
-
你有没有得到解决方案没有编译错误?