2013-11-27 54 views
0

我有一個程序,允許用戶設置客戶端/服務器來控制/運行遠程位置的命令。現在我試圖實現服務器插件,並通過加載當前運行目錄中包含的文件夾中的每個.vb文件來做到這一點。一切都很好,外部文件的代碼編譯得很好......唯一的問題是,當我嘗試編譯腳本並使用其中的一個方法時,它不會返回任何內容。如何讓VBCodeProvider返回對象

這裏有一些代碼供您檢查。我的錯誤是在第二。任何想法如何解決這個問題?

的互動接口方面: 「模式」 的

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 

回答

0

下面一行是錯誤的。

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

你需要通過加載的類來搜索一個實現你的接口(它是VB自動爲您生成的類我命名空間的對象,如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 
+0

這是從很久以前,但我仍然要感謝你。我經常提到這篇文章,並將它展示給其他許多人,這是一個很大的幫助。再次感謝! – matthew