我使用以下答案來測驗編譯代碼:
https://stackoverflow.com/a/21382083/9942758
https://stackoverflow.com/a/14711110/9942758
這是我的代碼:
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 介面,則不會出現編譯器錯誤,但是從“類腳本”轉換為 IScript 會失敗。
我在這里錯過了什么?
uj5u.com熱心網友回復:
從這里開始,這是有效的,然后添加回我洗掉的內容。基本上,這段代碼看到了介面,所以肯定有其他問題。
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/378923.html
