最终用户定义的代码 - 如何使用现有的 类 和 ExecutingAssembly 中的对象
end-user defined code - how to use existing classes and objects from the ExecutingAssembly
我有一个类似于 OP 在 How to load an internal class in end-user compiled code ? (advanced) 中的 winform,其中我有一个文本框,它将成为最终用户代码的来源,当我点击按钮。
以下是部分代码(其中大部分是从 How to load an internal class in end-user compiled code ? (advanced) 复制而来的:
Imports System
Imports System.CodeDom.Compiler
Imports System.Reflection
Imports System.Text
Public Class Form1
Private Sub ExecuteB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExecuteB.Click
Dim Code As String = Me.CodeToExec.Text
Dim CompilerResult As CompilerResults
CompilerResult = Compile(Code)
End Sub
Public Function Compile(ByVal Code As String) As CompilerResults
Dim CodeProvider As New VBCodeProvider
Dim CodeCompiler As System.CodeDom.Compiler.CodeDomProvider = CodeDomProvider.CreateProvider("VisualBasic")
Dim Parameters As New System.CodeDom.Compiler.CompilerParameters
Parameters.GenerateExecutable = False
Parameters.ReferencedAssemblies.Add("System.dll")
Parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll")
Parameters.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
Dim CompilerResult As CompilerResults = CodeCompiler.CompileAssemblyFromSource(Parameters, Code)
If CompilerResult.Errors.HasErrors Then
CompileTB.Clear()
For i = 0 To CompilerResult.Errors.Count - 1
CompileTB.AppendText(CompilerResult.Errors(i).ErrorText & vbCrLf)
Next
Return Nothing
Else
Return CompilerResult
End If
End Function
End Class
我的控件是:CodeToExec 是用户放置自定义代码的文本框,CompileTB 是另一个列出错误的文本框,ExecuteB 是按钮。我的程序中还有其他 classes 和对象,这里是我想使用的 classes 之一:
Public Class ExceptionCriteria
Private _CriteriaName As String
Public Property CriteriaName As String
Get
CriteriaName = _CriteriaName
End Get
Set(value As String)
_CriteriaName = value
End Set
End Property
Private _RuleSet As List(Of String)
Public Property RuleSet As List(Of String)
Get
RuleSet = _RuleSet
End Get
Set(value As List(Of String))
_RuleSet = value
End Set
End Property
Private _SerializationFilePath As String
Public Property SerializationFilePath As String
Get
SerializationFilePath = _SerializationFilePath
End Get
Set(value As String)
_SerializationFilePath = value
End Set
End Property
Public Sub AddRule(newRule As String)
If IsNothing(_RuleSet) Then
_RuleSet = New List(Of String)
End If
_RuleSet.Add(newRule)
End Sub
End Class
这是我想要 use/set 在 Form1 class 中的成员之一:
Public comparisondate As Date = #2/20/2015#
我的问题是,我想 access/modify 执行程序集中的对象、成员和属性,并根据那里的自定义 classes 创建新对象。我该怎么做?
我碰到了答案,我缺少的是
Parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)
然后我只需要将程序和成员共享。希望这也能帮助到和我一样刚好遇到同样问题并路过此页的新手。
如果你想使用现有的 类,你应该知道如何(自)引用以及如何传递参数。这是一个小例子:
不要忘记在生成的代码中Imports YourProjectName
。
例子Class做所有必要的事情
Imports System.CodeDom.Compiler
Imports System.Reflection
Public Class MyHelloCompiler
Private Shared _ass As Assembly
Private Shared _YourClass As Type
Private Shared _YourMethod As MethodInfo
Private Shared _YourClassInstance As Object
Public Sub New()
'Code to compile and instantiate the compiled class for later use:
Dim opt As New CompilerParameters _
(Nothing, String.Empty, False)
opt.GenerateExecutable = False
opt.GenerateInMemory = True
' Following is the important self reference
opt.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)
Console.WriteLine (MyCodeToCompile)
Dim res As CompilerResults = New VBCodeProvider().CompileAssemblyFromSource (opt, MyCodeToCompile)
_ass = res.CompiledAssembly
_YourClass = _ass.GetType ("MyExampleClass")
_YourMethod = _YourClass.GetMethod ("MyExampleProperty")
_YourClassInstance = Activator.CreateInstance ( _YourClass)
End Sub
Public Class MyExampleClass()
Public Property MyExampleProperty as String
End Class
Public Function RunCompiledCodeWithParams( _
instanceOfExampleClass as MyExampleClass) as String
Dim params As Object() = New Object() {instanceOfExampleClass}
Return CStr(_YourMethod.Invoke(_YourClassInstance, params))
End Function
Private Function MyCodeToCompile() as String
Return _
"Imports System" & vbCrLf & _
"Imports YourProjectName" & vbCrLf & _
"Public Class ClassToCompile" & vbCrLf & _
" Public Shared Function GetExampleProperty(prmExampleClassInstance as MyExampleClass) as String" & vbcrlf & _
" Return prmExampleClassInstance.MyExampleProperty" & vbcrlf & _
" End Function" & vbcrlf & _
"End Class"
End Function
End Class
在上面调用:
'....
Dim MyTestCompile As MyHelloCompiler = New MyHelloCompiler
Dim MyDummyClass As MyExampleClass = New MyExampleClass
MyDummyClass.MyExampleProperty = "I am the property value"
Dim MyResult as String = _
MyTestCompile.RunCompiledCodeWithParams(MyDummyClass)
'....
我有一个类似于 OP 在 How to load an internal class in end-user compiled code ? (advanced) 中的 winform,其中我有一个文本框,它将成为最终用户代码的来源,当我点击按钮。
以下是部分代码(其中大部分是从 How to load an internal class in end-user compiled code ? (advanced) 复制而来的:
Imports System
Imports System.CodeDom.Compiler
Imports System.Reflection
Imports System.Text
Public Class Form1
Private Sub ExecuteB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExecuteB.Click
Dim Code As String = Me.CodeToExec.Text
Dim CompilerResult As CompilerResults
CompilerResult = Compile(Code)
End Sub
Public Function Compile(ByVal Code As String) As CompilerResults
Dim CodeProvider As New VBCodeProvider
Dim CodeCompiler As System.CodeDom.Compiler.CodeDomProvider = CodeDomProvider.CreateProvider("VisualBasic")
Dim Parameters As New System.CodeDom.Compiler.CompilerParameters
Parameters.GenerateExecutable = False
Parameters.ReferencedAssemblies.Add("System.dll")
Parameters.ReferencedAssemblies.Add("System.Windows.Forms.dll")
Parameters.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
Dim CompilerResult As CompilerResults = CodeCompiler.CompileAssemblyFromSource(Parameters, Code)
If CompilerResult.Errors.HasErrors Then
CompileTB.Clear()
For i = 0 To CompilerResult.Errors.Count - 1
CompileTB.AppendText(CompilerResult.Errors(i).ErrorText & vbCrLf)
Next
Return Nothing
Else
Return CompilerResult
End If
End Function
End Class
我的控件是:CodeToExec 是用户放置自定义代码的文本框,CompileTB 是另一个列出错误的文本框,ExecuteB 是按钮。我的程序中还有其他 classes 和对象,这里是我想使用的 classes 之一:
Public Class ExceptionCriteria
Private _CriteriaName As String
Public Property CriteriaName As String
Get
CriteriaName = _CriteriaName
End Get
Set(value As String)
_CriteriaName = value
End Set
End Property
Private _RuleSet As List(Of String)
Public Property RuleSet As List(Of String)
Get
RuleSet = _RuleSet
End Get
Set(value As List(Of String))
_RuleSet = value
End Set
End Property
Private _SerializationFilePath As String
Public Property SerializationFilePath As String
Get
SerializationFilePath = _SerializationFilePath
End Get
Set(value As String)
_SerializationFilePath = value
End Set
End Property
Public Sub AddRule(newRule As String)
If IsNothing(_RuleSet) Then
_RuleSet = New List(Of String)
End If
_RuleSet.Add(newRule)
End Sub
End Class
这是我想要 use/set 在 Form1 class 中的成员之一:
Public comparisondate As Date = #2/20/2015#
我的问题是,我想 access/modify 执行程序集中的对象、成员和属性,并根据那里的自定义 classes 创建新对象。我该怎么做?
我碰到了答案,我缺少的是
Parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)
然后我只需要将程序和成员共享。希望这也能帮助到和我一样刚好遇到同样问题并路过此页的新手。
如果你想使用现有的 类,你应该知道如何(自)引用以及如何传递参数。这是一个小例子:
不要忘记在生成的代码中
Imports YourProjectName
。例子Class做所有必要的事情
Imports System.CodeDom.Compiler Imports System.Reflection Public Class MyHelloCompiler Private Shared _ass As Assembly Private Shared _YourClass As Type Private Shared _YourMethod As MethodInfo Private Shared _YourClassInstance As Object Public Sub New() 'Code to compile and instantiate the compiled class for later use: Dim opt As New CompilerParameters _ (Nothing, String.Empty, False) opt.GenerateExecutable = False opt.GenerateInMemory = True ' Following is the important self reference opt.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location) Console.WriteLine (MyCodeToCompile) Dim res As CompilerResults = New VBCodeProvider().CompileAssemblyFromSource (opt, MyCodeToCompile) _ass = res.CompiledAssembly _YourClass = _ass.GetType ("MyExampleClass") _YourMethod = _YourClass.GetMethod ("MyExampleProperty") _YourClassInstance = Activator.CreateInstance ( _YourClass) End Sub Public Class MyExampleClass() Public Property MyExampleProperty as String End Class Public Function RunCompiledCodeWithParams( _ instanceOfExampleClass as MyExampleClass) as String Dim params As Object() = New Object() {instanceOfExampleClass} Return CStr(_YourMethod.Invoke(_YourClassInstance, params)) End Function Private Function MyCodeToCompile() as String Return _ "Imports System" & vbCrLf & _ "Imports YourProjectName" & vbCrLf & _ "Public Class ClassToCompile" & vbCrLf & _ " Public Shared Function GetExampleProperty(prmExampleClassInstance as MyExampleClass) as String" & vbcrlf & _ " Return prmExampleClassInstance.MyExampleProperty" & vbcrlf & _ " End Function" & vbcrlf & _ "End Class" End Function End Class
在上面调用:
'.... Dim MyTestCompile As MyHelloCompiler = New MyHelloCompiler Dim MyDummyClass As MyExampleClass = New MyExampleClass MyDummyClass.MyExampleProperty = "I am the property value" Dim MyResult as String = _ MyTestCompile.RunCompiledCodeWithParams(MyDummyClass) '....