gpt4 book ai didi

vb.net - 从 .txt 文件加载 VB.net 代码并使用 System.CodeDom.Compiler 即时执行

转载 作者:行者123 更新时间:2023-12-01 07:26:37 25 4
gpt4 key购买 nike

我已经在这篇文章中找到了这个问题的答案:https://stackoverflow.com/a/14711110/1764912

但我的下一个查询是,当我尝试在此动态代码中声明 DataTable 或 MsgBox 时,它给我一个错误,“Type 'DataTable' is not defined”和“Type 'MsgBox' is not defined” .如果我使用动态代码中的第一行添加导入:

Imports System.Data

Imports System.Data.DataTable

或者如果我在 GenerateScript() 函数中使用以下任何代码(请参阅 https://stackoverflow.com/a/14711110/1764912 以了解 GenerateScript() 函数)

Dim importDataNameSpace As String = GetType(DataTable).Namespace
Dim codeArray() As String = New String() {"Imports " & importDataNameSpace & Environment.NewLine & code}

或者如果我使用

Dim codeArray() As String = New String() {"Imports System.Data" & Environment.NewLine & code}

Dim codeArray() As String = New String() {"Imports System.Data.DataTable" & Environment.NewLine & code}

在上述所有情况下,它都会给我一个错误“System.Data 不包含任何公共(public)成员或找不到”。

最佳答案

除非您首先引用 库,否则导入命名空间对您没有任何作用。如果未引用该库,则您导入的命名空间实际上是空的。

正如其他人在上面的评论中提到的,只是因为您在项目中引用了 System.Data.dll 库,并不意味着它也被您所引用的程序集引用正在动态编译。每个程序集都需要直接引用它需要的所有程序集。动态编译的程序集也不异常(exception)。

通过 CompilerParameters.ReferencedAssemblies.Add 方法将引用添加到动态程序集。你可以在我对你链接到的问题的回答中看到一个例子。在该示例中,我将动态程序集引用返回给主程序集,以便它可以使用 IScript 接口(interface)。但是,您可以根据需要添加任意数量的引用。要同时添加对 System.Data.dll 的引用,您可以这样做:

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

由于 System.Data.dll 程序集位于 GAC 中,因此您无需指定完整路径。另请注意,为了使用 DataTable,您还需要添加对 System.Xml.dll 的引用。您会在运行代码后立即发现这一点。

因此,如果您定义了上述方法,并且定义了以下接口(interface):

Public Interface IScript
Function DoWork() As String
End Interface

然后,你可以这样调用它:

Dim builder As New StringBuilder()
builder.AppendLine("Public Class Script")
builder.AppendLine(" Implements IScript")
builder.AppendLine(" Public Function DoWork() As String Implements IScript.DoWork")
builder.AppendLine(" Dim table As New System.Data.DataTable()")
builder.AppendLine(" table.TableName = ""Hello World""")
builder.AppendLine(" Return table.TableName")
builder.AppendLine(" End Function")
builder.AppendLine("End Class")
Dim script As IScript = GenerateScript(builder.ToString())
Console.WriteLine(script.DoWork()) ' Outputs "Hello World"

关于vb.net - 从 .txt 文件加载 VB.net 代码并使用 System.CodeDom.Compiler 即时执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21379926/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com