如何使用CodeDOM编译Windows Form Application源代码
How to compile Windows Form Application source code using CodeDOM
我需要创建一个 VB.NET 应用程序,它获取 Windows 表单应用程序 的源代码并进行编译。我用这个 link 作为参考。
Windows 我要创建的表单应用程序
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MsgBox("test")
End Sub
结束Class
我的VB.NET编译代码的应用程序
Imports System.IO
Imports System.Reflection
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports Microsoft.VisualBasic
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim codeProvider As New VBCodeProvider()
Dim icc As ICodeCompiler = codeProvider.CreateCompiler
Dim Output As String = "Out.exe"
Dim ButtonObject As Button = CType(sender, Button)
textBox2.Text = ""
Dim parameters As New CompilerParameters()
Dim results As CompilerResults
'Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = True
parameters.OutputAssembly = Output
results = icc.CompileAssemblyFromSource(parameters, textBox1.Text)
If results.Errors.Count > 0 Then
'There were compiler errors
textBox2.ForeColor = Color.Red
Dim CompErr As CompilerError
For Each CompErr In results.Errors
textBox2.Text = textBox2.Text &
"Line number " & CompErr.Line &
", Error Number: " & CompErr.ErrorNumber &
", '" & CompErr.ErrorText & ";" &
Environment.NewLine & Environment.NewLine
Next
Else
'Successful Compile
textBox2.ForeColor = Color.Blue
textBox2.Text = "Success!"
'If we clicked run then launch the EXE
If ButtonObject.Text = "Run" Then Process.Start(Output)
End If
End Sub
Textbox1.text
包含我提供的第一个代码。当我 运行 程序时,它给我这个错误
Line number 0, Error Number: BC30420, ''Sub Main' was not found in 'Out'.;
Line number 2, Error Number: BC30002, 'Type 'EventArgs' is not defined.;
Line number 3, Error Number: BC30451, ''MsgBox' is not declared. It may be inaccessible due to its protection level.;
Line number 3, Error Number: BC32017, 'Comma, ')', or a valid expression continuation expected.;
嗯,你错过了很多东西。
在您将传递给 CodeDomProvider
的 CompilerParameters
中,您必须指定目标 exe 类型,默认为“/target:exe”,这意味着控制台可执行文件(然后编译器会尝试为入口点找到 Sub Main()),因此您必须为 WindowsForms 项目指定“/target:winexe”。
您还必须在要编译的源代码中指定所需的 Imports
...否则将无法解析,对于源代码所需的 .NET 程序集引用也是如此,您必须在 CompilerParameters
.
中指定所有这些
最后你应该指定主要的名称class然后你就可以编译它了。
我将展示一个您可以 adapt/replace 当前源代码的工作示例:
Public Shared ReadOnly WinFormsTemplate As String =
<a>
Imports System
Imports System.Windows.Forms
Namespace MyNamespace
Public NotInheritable Class Form1 : Inherits Form
Public Sub New()
Me.StartPosition = FormStartPosition.CenterScreen
End Sub
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As EventArgs) _
Handles MyBase.Shown
MessageBox.Show("VisualBasic.NET WinForms Template.")
End Sub
End Class
End Namespace
</a>.Value
Private Sub CompileSourceCode()
Dim cProvider As CodeDomProvider = New VBCodeProvider
Dim cParams As New CompilerParameters
Dim cResult As CompilerResults
Dim sourceCode As String = WinFormsTemplate
With cParams
.GenerateInMemory = False
.GenerateExecutable = True
.OutputAssembly = Path.Combine(My.Application.Info.DirectoryPath, ".\test.exe")
.CompilerOptions = "/target:winexe"
.ReferencedAssemblies.AddRange({"System.dll", "System.Windows.Forms.dll", "Microsoft.VisualBasic.dll"})
.MainClass = "MyNamespace.Form1"
End With
cResult = cProvider.CompileAssemblyFromSource(cParams, sourceCode)
cProvider.Dispose()
End Sub
我需要创建一个 VB.NET 应用程序,它获取 Windows 表单应用程序 的源代码并进行编译。我用这个 link 作为参考。
Windows 我要创建的表单应用程序
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MsgBox("test")
End Sub
结束Class
我的VB.NET编译代码的应用程序
Imports System.IO
Imports System.Reflection
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports Microsoft.VisualBasic
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim codeProvider As New VBCodeProvider()
Dim icc As ICodeCompiler = codeProvider.CreateCompiler
Dim Output As String = "Out.exe"
Dim ButtonObject As Button = CType(sender, Button)
textBox2.Text = ""
Dim parameters As New CompilerParameters()
Dim results As CompilerResults
'Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = True
parameters.OutputAssembly = Output
results = icc.CompileAssemblyFromSource(parameters, textBox1.Text)
If results.Errors.Count > 0 Then
'There were compiler errors
textBox2.ForeColor = Color.Red
Dim CompErr As CompilerError
For Each CompErr In results.Errors
textBox2.Text = textBox2.Text &
"Line number " & CompErr.Line &
", Error Number: " & CompErr.ErrorNumber &
", '" & CompErr.ErrorText & ";" &
Environment.NewLine & Environment.NewLine
Next
Else
'Successful Compile
textBox2.ForeColor = Color.Blue
textBox2.Text = "Success!"
'If we clicked run then launch the EXE
If ButtonObject.Text = "Run" Then Process.Start(Output)
End If
End Sub
Textbox1.text
包含我提供的第一个代码。当我 运行 程序时,它给我这个错误
Line number 0, Error Number: BC30420, ''Sub Main' was not found in 'Out'.;
Line number 2, Error Number: BC30002, 'Type 'EventArgs' is not defined.;
Line number 3, Error Number: BC30451, ''MsgBox' is not declared. It may be inaccessible due to its protection level.;
Line number 3, Error Number: BC32017, 'Comma, ')', or a valid expression continuation expected.;
嗯,你错过了很多东西。
在您将传递给 CodeDomProvider
的 CompilerParameters
中,您必须指定目标 exe 类型,默认为“/target:exe”,这意味着控制台可执行文件(然后编译器会尝试为入口点找到 Sub Main()),因此您必须为 WindowsForms 项目指定“/target:winexe”。
您还必须在要编译的源代码中指定所需的 Imports
...否则将无法解析,对于源代码所需的 .NET 程序集引用也是如此,您必须在 CompilerParameters
.
最后你应该指定主要的名称class然后你就可以编译它了。
我将展示一个您可以 adapt/replace 当前源代码的工作示例:
Public Shared ReadOnly WinFormsTemplate As String =
<a>
Imports System
Imports System.Windows.Forms
Namespace MyNamespace
Public NotInheritable Class Form1 : Inherits Form
Public Sub New()
Me.StartPosition = FormStartPosition.CenterScreen
End Sub
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As EventArgs) _
Handles MyBase.Shown
MessageBox.Show("VisualBasic.NET WinForms Template.")
End Sub
End Class
End Namespace
</a>.Value
Private Sub CompileSourceCode()
Dim cProvider As CodeDomProvider = New VBCodeProvider
Dim cParams As New CompilerParameters
Dim cResult As CompilerResults
Dim sourceCode As String = WinFormsTemplate
With cParams
.GenerateInMemory = False
.GenerateExecutable = True
.OutputAssembly = Path.Combine(My.Application.Info.DirectoryPath, ".\test.exe")
.CompilerOptions = "/target:winexe"
.ReferencedAssemblies.AddRange({"System.dll", "System.Windows.Forms.dll", "Microsoft.VisualBasic.dll"})
.MainClass = "MyNamespace.Form1"
End With
cResult = cProvider.CompileAssemblyFromSource(cParams, sourceCode)
cProvider.Dispose()
End Sub