简体   繁体   English

如何获取VBCodeProvider返回对象

[英]How do I get VBCodeProvider to return an object

I have a program that allows users to setup a client/server to control/run commands from a remote location. 我有一个程序,允许用户设置客户端/服务器以从远程位置控制/运行命令。 Now i'm trying to implement server plugins, and I'm doing that by loading every .vb file in a folder contained inside the current running directory. 现在,我正在尝试实现服务器插件,并且通过将每个.vb文件加载到当前运行目录中包含的文件夹中来进行此操作。 Everything is great, and the code from the external files compiles just fine... Only problem is, Its returning nothing when I try to compile the script and use one of the methods inside it. 一切都很好,并且来自外部文件的代码也可以编译……唯一的问题是,当我尝试编译脚本并使用其中的一种方法时,它什么也没有返回。

Here's some code for you to check out. 这是一些代码供您签出。 My error is in the 2nd. 我的错误是第二。 Any idea on how to fix this? 关于如何解决此问题的任何想法?

The Interaction Interface: 交互界面:

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


Detection/Loading of the "Modes" (add-ins): 检测/加载“模式”(加载项):

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' Function '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


The Testing file 'test.vb': 测试文件“ 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

the following line is wrong. 下一行是错误的。

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

You need to search through the loaded classes for one implementing your interface (it being VB you automatically get classes generated for the My namespace objects such as My.Computer) 您需要在加载的类中搜索一个实现您的接口的类(在VB中,您会自动获取为My命名空间对象(例如My.Computer)生成的类。

Try this instead 试试这个

        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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM