如何让VBCodeProvider返回一个对象

时间:2013-11-27 07:31:04

标签: vb.net compilation

我有一个程序,允许用户设置客户端/服务器来控制/运行来自远程位置的命令。现在我正在尝试实现服务器插件,我正在通过将每个.vb文件加载到当前运行目录中包含的文件夹中来实现。一切都很好,外部文件的代码编译得很好......唯一的问题是,当我尝试编译脚本并使用其中的一个方法时,它什么也没有返回。

这里有一些代码供您查看。我的错误是在第二个。关于如何解决这个问题的任何想法?

互动界面:

Public Interface LinkingInterface
    Property name As String
    Property statetag As String
    Sub selected(ByVal Sock As Integer)
    Sub deselected(ByVal Sock As Integer)
    Sub load()
    Function generateOutput(ByVal input As String, ByVal Sock As Integer) As String
End Interface


检测/加载“模式”(加载项):

For Each file In My.Computer.FileSystem.GetFiles("modes\")
            Dim thisMode As LinkingInterface = LoadMode(My.Computer.FileSystem.ReadAllText(file))
            thisMode.load() '<---------------------------My error is here, saying its a null ref.
            modes_InterfaceCollection.Add(thisMode)     'Public modes_InterfaceCollection As New Microsoft.VisualBasic.Collection()
            modes_nameIndex.Add(thisMode.name)          'Public modes_nameIndex As New Specialized.StringCollection()
        Next


'LoadMode'功能

Public Function LoadMode(ByVal code As String) As LinkingInterface
        Using provider As New VBCodeProvider()
            Dim parameters As New CompilerParameters()
            parameters.GenerateInMemory = True
            parameters.ReferencedAssemblies.Add(Reflection.Assembly.GetExecutingAssembly().Location)
            parameters.MainClass = "Remote_Command_Line.MainModule"
            Dim interfaceNamespace As String = GetType(LinkingInterface).Namespace
            Dim codeBuilder As New Text.StringBuilder
            Dim namespaces() As String = New String() {"Microsoft.VisualBasic", "System", "System.Console", "System.Collections", "System.Collections.Generic", _
                                                       "System.Data", "System.Diagnostics", "Remote_Command_Line.MainModule"}
            Dim codeString As New StringBuilder
            For Each namespacestring As String In namespaces
                codeString.AppendLine("Imports " & namespacestring)
            Next
            codeString.AppendLine(code)
            Dim results As CompilerResults = provider.CompileAssemblyFromSource(parameters, codeString.ToString)

            'I commented out this just for debugging purposes
            'If results.Errors.HasErrors Then
            'For Each scriptError As CompilerError In results.Errors
            'WriteLine(scriptError.ToString)
            'Next
            'Else
            Return CType(results.CompiledAssembly.CreateInstance(results.CompiledAssembly.GetType.Name), LinkingInterface)
            'End If
        End Using
    End Function


测试文件'test.vb':

Public Class test_mode
    'Designed for RCL mode 1.0b
    'Matthew 2013
    'used for managing the local filesystem.  



    '####################################
#Region "Properties"
    'all of these properties listed are required --------------------
    Implements LinkingInterface
    Property name As String Implements LinkingInterface.name         'the name the client refers to you in the 'modeswitch' command
    Property statetag As String Implements LinkingInterface.statetag 'short tag displayed on the client when active before the input signal '>'
    '----------------------------------------------------------------
    Public curDirDatabank As New Specialized.StringCollection()

#End Region
    '####################################





    '####################################
#Region "Subs"

    'Its required to have, but not required to do anything. This load sub is here for any modes that may require an initialization
    Private Sub load() Implements LinkingInterface.load 'REQUIRED
        name = "file" : statetag = "file"
        MsgBox("Testing: It's loaded")
    End Sub

    Private Sub selected(ByVal Sock As Integer) Implements LinkingInterface.selected
        MsgBox("Testing: '" & Sock & "' selected the File mode")
    End Sub

    Private Sub deselected(ByVal Sock As Integer) Implements LinkingInterface.deselected
        MsgBox("Testing: '" & Sock & "' deselected the File mode")
    End Sub

    Private Function generateOutput(ByVal input As String, ByVal Sock As Integer) As String Implements LinkingInterface.generateOutput 'REQUIRED
        Return ("Testing: '" & Sock & "' said '" & input & "'")
    End Function

#End Region
    '####################################

End Class

1 个答案:

答案 0 :(得分:0)

以下行错误。

Return CType(results.CompiledAssembly.CreateInstance(results.CompiledAssembly.GetType.Name), LinkingInterface)

您需要在已加载的类中搜索实现接口的类(它是VB,您自动获取为My命名空间对象生成的类,如My.Computer)

试试这个

        For Each t As Type In results.CompiledAssembly.GetTypes()
            If t.GetInterface(GetType(LinkingInterface).Name) IsNot Nothing Then
                Return CType(results.CompiledAssembly.CreateInstance(t.Name), LinkingInterface)
            End If
        Next

        Return Nothing