System.CodeDom.Compiler 未定义接口 IScript

System.CodeDom.Compiler Interface IScript not defined

我使用了以下答案来测试编译代码:

这是我的代码:

    Public Interface IScript
        Property theDataTable As System.Data.DataTable
        Sub DoWork()
    End Interface

    Public Function GenerateScript(code As String) As IScript

        Using provider As New VBCodeProvider()

            Dim parameters As New CompilerParameters()

            parameters.GenerateInMemory = True
            parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)
            parameters.ReferencedAssemblies.Add("System.Data.dll")
            parameters.ReferencedAssemblies.Add("System.Xml.dll")
            parameters.ReferencedAssemblies.Add("C:\Users\<User>\source\repos\MikroTikTable\MikroTikTable\bin\Debug\Renci.SshNet.dll")

            Dim interfaceNamespace As String = GetType(IScript).Namespace
            Dim codeArray() As String = New String() {"Imports " & interfaceNamespace & Environment.NewLine & code}
            Dim results As CompilerResults = provider.CompileAssemblyFromSource(parameters, codeArray)

            If results.Errors.HasErrors Then
                Throw New Exception("Failed to compile script")
            Else
                Return CType(results.CompiledAssembly.CreateInstance("Script"), IScript)
            End If
        End Using
    End Function

    Public Function GetTable(theHost As String, theUser As String, thePwd As String, theCmd As String) As DataTable

        Dim builder As New StringBuilder()

        builder.AppendLine("Imports Renci.SshNet")
        builder.AppendLine("Imports System.Data")
        builder.AppendLine("Imports Microsoft.VisualBasic")
        builder.AppendLine("Imports System.Text")
        builder.AppendLine("Imports System.Text.RegularExpressions")
        'builder.AppendLine("Public Interface IScript")
        'builder.AppendLine("    Property theDataTable As DataTable")
        'builder.AppendLine("    Sub DoWork()")
        'builder.AppendLine("End Interface")
        builder.AppendLine("Public Class Script")
        builder.AppendLine("    Implements IScript")
        builder.AppendLine("    Public Property theDataTable As DataTable Implements IScript.theDataTable")
        builder.AppendLine("    Public Sub DoWork() Implements IScript.DoWork")
        builder.AppendLine($"        Dim theConnectionInfo As PasswordConnectionInfo = New PasswordConnectionInfo(""{theHost}"", ""{theUser}"", ""{thePwd}"")")
        builder.AppendLine("        Dim sshClient = New SshClient(theConnectionInfo)")
        builder.AppendLine($"        Dim sshCmd = ""{theCmd}"".Replace(vbCrLf, vbCr)")
        builder.AppendLine("         Dim cmdArgs As New clsCommandData With {.cmd = sshCmd}")
        builder.AppendLine("        sshClient.Connect()")
        builder.AppendLine("        cmdArgs.output = sshClient.RunCommand(cmdArgs.cmd)")
        builder.AppendLine("        Dim resultText = cmdArgs.output.Result.Replace(vbCr, """")")
        builder.AppendLine("        SshClient.Disconnect()")
        builder.AppendLine("        resultText = resultText.Replace(vbLf, vbCrLf)")
        builder.AppendLine("        resultText = Regex.Replace(resultText, ""^\s+$[\r\n]*"", ""|"", RegexOptions.Multiline)")
        builder.AppendLine("        Dim interfaceRows() = resultText.Split(""|"")")
        builder.AppendLine("        Dim newString As New StringBuilder")
        builder.AppendLine("        For i As Integer = 0 To interfaceRows.Length - 2")
        builder.AppendLine("            Dim interfaceRow = interfaceRows(i)")
        builder.AppendLine("            interfaceRow = interfaceRow.Replace(""|"", """")")
        builder.AppendLine("            interfaceRow = Trim(interfaceRow)")
        builder.AppendLine("            interfaceRow = interfaceRow.Replace(vbCrLf, "" "")")
        builder.AppendLine("             interfaceRow = Regex.Replace(interfaceRow, "" {2,}"", "" "")")
        builder.AppendLine("            Dim startPos = interfaceRow.LastIndexOf(""="")")
        builder.AppendLine("            Do While startPos > -1")
        builder.AppendLine("                Dim theSpacePos = interfaceRow.LastIndexOf("" "", startPos)")
        builder.AppendLine("                If theSpacePos > -1 Then interfaceRow = interfaceRow.Remove(theSpacePos, 1).Insert(theSpacePos, ""|"")")
        builder.AppendLine("                startPos = interfaceRow.LastIndexOf(""="", theSpacePos)")
        builder.AppendLine("            Loop")
        builder.AppendLine("            Dim fieldCandidates() = interfaceRow.Split(""|"")")
        builder.AppendLine("            For j As Integer = 1 To fieldCandidates.Length - 1")
        builder.AppendLine("                Dim fieldCandidate = fieldCandidates(j)")
        builder.AppendLine("                Dim splitField() = fieldCandidate.Split(""="")")
        builder.AppendLine("                If Not theDataTable.Columns.Contains(splitField(0)) Then theDataTable.Columns.Add(splitField(0), GetType(String))")
        builder.AppendLine("            Next")
        builder.AppendLine("            Dim addRow = theDataTable.NewRow")
        builder.AppendLine("            For j As Integer = 1 To fieldCandidates.Length - 1")
        builder.AppendLine("                Dim fieldCandidate = fieldCandidates(j)")
        builder.AppendLine("                Dim splitField() = fieldCandidate.Split(""="")")
        builder.AppendLine("                addRow(splitField(0)) = splitField(1)")
        builder.AppendLine("            Next")
        builder.AppendLine("            theDataTable.Rows.Add(addRow)")
        builder.AppendLine("        Next")
        builder.AppendLine("    End Sub")
        builder.AppendLine("    Private Class clsCommandData")
        builder.AppendLine("        Public cmd As String")
        builder.AppendLine("        Public output As SshCommand")
        builder.AppendLine("    End Class")
        builder.AppendLine("End Class")

        'Dim theText = builder.ToString()
        Dim script As IScript = GenerateScript(builder.ToString())

        script.DoWork()

        Return script.theDataTable
    End Function

我不断收到编译器错误“类型 'IScript' 未定义”

如果我在我的 stringbuilder 中显式定义 IScript 接口,我不会收到编译器错误,但是从“Class 脚本”转换为 IScript 会失败。

我在这里错过了什么?

从这里开始,这行得通,然后添加我删除的内容。基本上,这段代码看到了接口,所以肯定还有其他问题。

Imports System.CodeDom.Compiler
Imports System.Reflection

Module Module1
    Sub Main()
        Dim bar = New Foo()
        Dim dt = bar.GetTable()
    End Sub
End Module

Public Interface IScript
    Property theDataTable As System.Data.DataTable
    Sub DoWork()
End Interface

Public Class Foo
    Public Function GenerateScript(code As String) As IScript
        Using provider As New VBCodeProvider()
            Dim parameters As New CompilerParameters()
            parameters.GenerateInMemory = True
            parameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location)
            parameters.ReferencedAssemblies.Add("System.Data.dll")
            parameters.ReferencedAssemblies.Add("System.Xml.dll")
            Dim interfaceNamespace As String = GetType(IScript).Namespace
            Dim codeArray() As String = New String() {"Imports " & interfaceNamespace & Environment.NewLine & code}
            Dim results As CompilerResults = provider.CompileAssemblyFromSource(parameters, codeArray)
            If results.Errors.HasErrors Then
                Throw New Exception("Failed to compile script")
            Else
                Return CType(results.CompiledAssembly.CreateInstance("Script"), IScript)
            End If
        End Using
    End Function
    Public Function GetTable() As DataTable
        Dim text = "
Imports System.Data
Imports Microsoft.VisualBasic
Public Class Script
    Implements IScript
    Public Property theDataTable As DataTable Implements IScript.theDataTable
    Public Sub DoWork() Implements IScript.DoWork
        MsgBox(""Hello"")
    End Sub
End Class"
        Dim script As IScript = GenerateScript(text)
        script.DoWork()
        Return script.theDataTable
    End Function
End Class