最终用户定义的代码 - 如何使用ExecutingAssembly

时间:2015-05-15 02:48:06

标签: vb.net .net-assembly

我有一个类似于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是按钮。我的程序中还有其他类和对象,这是我想要使用的类之一:

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

这是我想在Form1类中使用/设置的成员之一:

Public comparisondate As Date = #2/20/2015#

我的问题是,我想访问/修改执行程序集中的对象,成员,属性,并根据那里的自定义类创建新对象。我怎么能这样做?

2 个答案:

答案 0 :(得分:1)

我已经碰到了答案,我缺少的是

private class MyListAdapter extends ArrayAdapter<CommentInfo> {


    public MyListAdapter()
    {
        super(Comment.this, R.layout.listview_xml, myComments);
    }
    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent)
    {
        itemView = convertView;

        if(itemView == null)
        {
            itemView = getLayoutInflater().inflate(R.layout.listview_xml, parent, false);

        }
        CommentInfo currentComment = myComments.get(position);


        TextView tvLikes = (TextView) itemView.findViewById(R.id.tvLikes);
        tvLikes.setText(currentComment.likes);

        ImageView ivLikes = (ImageView) itemView.findViewById(R.id.likeBtn);
        ivLikes.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                likePosition = position;                    
                TextView tvlikes1 = (TextView) convertView.findViewById(R.id.tvLikes);
                // Here, i will get the correct value from DB and set it.
                // I am setting 999 for sample purpose
                tvlikes1.setText("999");
            }
        });
        return itemView;
    }
}

然后我只需要让程序和成员共享。我希望这也能帮助像我这样的新手碰巧遇到同样的问题并通过这个页面。

答案 1 :(得分:0)

如果您想使用现有的类,您应该知道如何(自我)引用以及如何提供参数。这是一个小例子:

  1. 请勿忘记生成的代码中的Imports YourProjectName

  2. 示例类来做所有必要的事情

    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
    
  3. 调用上述内容:

    '....
    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)
    '....