动态代码编译解决办法
动态代码编译
我想要动态执行文本输入的代码:
已经写好的编译程序,如下
Imports System.CodeDom.Compiler
Public Class calcul
Public Property WindowStyle As ProcessWindowStyle
Dim resultat As Double
Private Sub Form7_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim referenceAssemblies As String() = {"System.Windows.Forms.dll"}
Dim cp As New CompilerParameters(referenceAssemblies, "abc.exe", False)
cp.ReferencedAssemblies.Add("System.dll")
cp.ReferencedAssemblies.Add("System.data.dll")
cp.ReferencedAssemblies.Add("System.xml.dll")
cp.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
cp.GenerateExecutable = True
'RichTextBox1.Text = transform.txtcodefinal
Dim sources() As String = {RichTextBox1.Text}
Dim cr As CompilerResults = New VBCodeProvider().CompileAssemblyFromSource(cp, sources)
If cr.Errors.Count > 0 Then
MessageBox.Show("语法有错误,请检查!")
MsgBox(cr.Errors.Count)
Else
Dim proRestart As New Process()
proRestart.StartInfo.WindowStyle = ProcessWindowStyle.Hidden '不显示窗体
proRestart.StartInfo.UseShellExecute = True
Dim strArgument As String = " /c dir c: > c:\11.txt" '启动参数
proRestart.StartInfo.Arguments = strArgument
proRestart.StartInfo.CreateNoWindow = True
proRestart.StartInfo.FileName = "abc.exe"
proRestart.Start()
'执行
End If
End Sub
End Class
编译文本为
imports System.Windows.Forms
imports System.Math
Public Class Class1
Shared Sub Main()
Dim resultat As Double
Dim a As Double
a = 2
resultat = 4*a
MessageBox.show(resultat)
End Sub
End Class
但是结果只能用messagebox显示,怎么才能在原程序中引用这个数据。
------解决方案--------------------
这相当于进程间通信了。
如果想简单点,可以编译Console程序,运行时重定向output。主程序就能收到output了。
或者编译的程序输出文件,主程序读取。
实时通信有点复杂,google C# 进程间通信,有很多中方法,管道,SendMessage,WCF, MSMQ等等。
------解决方案--------------------
原来弄报表的时候写过一个例子,看看是否能实现你要的功能
我想要动态执行文本输入的代码:
已经写好的编译程序,如下
Imports System.CodeDom.Compiler
Public Class calcul
Public Property WindowStyle As ProcessWindowStyle
Dim resultat As Double
Private Sub Form7_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim referenceAssemblies As String() = {"System.Windows.Forms.dll"}
Dim cp As New CompilerParameters(referenceAssemblies, "abc.exe", False)
cp.ReferencedAssemblies.Add("System.dll")
cp.ReferencedAssemblies.Add("System.data.dll")
cp.ReferencedAssemblies.Add("System.xml.dll")
cp.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll")
cp.GenerateExecutable = True
'RichTextBox1.Text = transform.txtcodefinal
Dim sources() As String = {RichTextBox1.Text}
Dim cr As CompilerResults = New VBCodeProvider().CompileAssemblyFromSource(cp, sources)
If cr.Errors.Count > 0 Then
MessageBox.Show("语法有错误,请检查!")
MsgBox(cr.Errors.Count)
Else
Dim proRestart As New Process()
proRestart.StartInfo.WindowStyle = ProcessWindowStyle.Hidden '不显示窗体
proRestart.StartInfo.UseShellExecute = True
Dim strArgument As String = " /c dir c: > c:\11.txt" '启动参数
proRestart.StartInfo.Arguments = strArgument
proRestart.StartInfo.CreateNoWindow = True
proRestart.StartInfo.FileName = "abc.exe"
proRestart.Start()
'执行
End If
End Sub
End Class
编译文本为
imports System.Windows.Forms
imports System.Math
Public Class Class1
Shared Sub Main()
Dim resultat As Double
Dim a As Double
a = 2
resultat = 4*a
MessageBox.show(resultat)
End Sub
End Class
但是结果只能用messagebox显示,怎么才能在原程序中引用这个数据。
------解决方案--------------------
这相当于进程间通信了。
如果想简单点,可以编译Console程序,运行时重定向output。主程序就能收到output了。
或者编译的程序输出文件,主程序读取。
实时通信有点复杂,google C# 进程间通信,有很多中方法,管道,SendMessage,WCF, MSMQ等等。
------解决方案--------------------
原来弄报表的时候写过一个例子,看看是否能实现你要的功能
- VB.NET code
Imports System.CodeDom.Compiler ''' <summary> ''' 报表类 ''' </summary> ''' <remarks></remarks> Public Class ReportHelp ''' <summary> ''' 验证代码是否可以编译通过 ''' </summary> ''' <param name="sourcecode">代码源文件</param> ''' <param name="sourceprovider">源文件开发语言vb/c#</param> ''' <returns>true:正常编译 other:编译错误</returns> ''' <remarks></remarks> Public Function check(ByVal sourcecode As String, ByVal sourceprovider As SourceProvider) As String Dim _provider As CodeDomProvider = CodeDomProvider.CreateProvider(sourceprovider) Dim _param As New CompilerParameters _param.ReferencedAssemblies.Add("System.dll") _param.ReferencedAssemblies.Add("System.Windows.Forms.dll") _param.ReferencedAssemblies.Add("System.Data.dll") _param.ReferencedAssemblies.Add("System.Drawing.dll") _param.ReferencedAssemblies.Add("System.Xml.dll") _param.GenerateExecutable = False _param.GenerateInMemory = True Dim _results As CompilerResults = _provider.CompileAssemblyFromSource(_param, New String() {sourcecode}) If _results.Errors.HasErrors = True Then Dim errormessage As String = "" Dim err As CompilerError For Each err In _results.Errors errormessage = (errormessage & err.ErrorText) Next Return errormessage Else Return "true" End If End Function ''' <summary> ''' 调用动态代码(报表专用) ''' </summary> ''' <param name="sourcecode">源代码</param> ''' <param name="sourceprovider">编译引擎</param> ''' <param name="funname">调用方法名称</param> ''' <param name="ds">dataset参数 注:使用dataset作为数据传递的途径</param> ''' <returns>返回处理结果dataset</returns> ''' <remarks></remarks> Public Function btnRun_Click(ByVal sourcecode As String, ByVal sourceprovider As SourceProvider, ByVal funname As String, ByVal ds As DataSet) As Object Dim _provider As CodeDomProvider = CodeDomProvider.CreateProvider(sourceprovider.ToString) Dim _param As New CompilerParameters _param.ReferencedAssemblies.Add("System.dll") _param.ReferencedAssemblies.Add("System.Windows.Forms.dll") _param.ReferencedAssemblies.Add("System.Data.dll") _param.ReferencedAssemblies.Add("System.Drawing.dll") _param.ReferencedAssemblies.Add("System.Xml.dll") _param.GenerateExecutable = False _param.GenerateInMemory = True Dim _results As CompilerResults = _provider.CompileAssemblyFromSource(_param, New String() {sourcecode}) If _results.Errors.HasErrors = True Then Dim errormessage As String = "" Dim err As CompilerError For Each err In _results.Errors errormessage = (errormessage & err.ErrorText) Next Throw New Exception(errormessage) Else Dim report As Object = _results.CompiledAssembly.CreateInstance("CodeGenerate.Report") Return report.GetType.GetMethod(funname).Invoke(report, New Object() {ds}) End If '/*示例代码如下*/ 'Namespace CodeGenerate ' Public Class Report ' Public Function execcmd(ByVal ds As DataSet) As DataSet ' ds.Tables(0).Rows(0)(0) = "测试一下:传递参数为" ' Return ds ' End Function ' End Class 'End Namespace '/*示例代码结束*/ End Function End Class ''' <summary> ''' 语言版本 ''' </summary> ''' <remarks></remarks> Public Enum SourceProvider VisualBasic CSharp End Enum