标签:
---恢复内容开始---
一般,我们都是通过Visual Studio(下面简称vs)来编写和编译vb.net应用程序的,但是,不少的人并不知道vs是通过何种方式编译程序的。今天,我们就来探讨一下编译vb.net程序的真正原理。
这篇随笔包含如下几个部分:
ok,首先来说说vs编译应用程序的方法。其实,vs是通过调用vbc.exe来编译vbnet应用程序的。vs把用户编写的代码文件和指定定的参数(引用,编译出的程序的类型,目标文件的保存位置等)一股脑的传给vbc,然后剩下的工作就交给vbc来做了。
其实,vbnet程序的编译并不像我们想象的那么困难。对于编译一些比较简单的代码,几行cmd命令就可以完全搞定。而且,这个vbc.exe并不是vs的专用附属,不论你是.net2.0还是最新的.net4.5.3预览版,只要你家有.net Framework,就能找到vbc。vbc的地址是 C:\Windows\Microsoft.NET\Framework\.net版本(比如v4.0.30319)\vbc.exe.
可以cmd来调用它。这是截图。
首先cd到指定路径下然后调用vbc。vbc功能强大,这里列出一部分。
这里详细介绍几个参数:
1./target
缩写为/t 他指定了编译类型。有四种选项 exe(将编译成控制台应用程序) ,winexe(将编译成 窗体应用程序),library(编译成类库【*.dll】)和module(编译成模块)。
例如 /t:exe
2./reference:<file_list>
缩写: /r 从指定的程序集引用元数据。 它的作用就相当于vs里的添加引用。可以通过指定这个参数来添加引用,vbc为我们默认引用了许多类库。他们保存在vbc.rsp里。默认的vbc.rsp也就是默认添加的引用如下。
下面我们来一个简单的vbc编译例子。
首先我们编写了一个最最简单的vb代码。如下:
Imports System.Windows.Forms Module Module1 Sub Main() MessageBox.Show("Hello World") End Sub End Module
我们把它保存到vbc的目录下。名为a.txt
我们调用cmd,cd 到指定目录下,调用vbc.exe执行下面的命令:vbc.exe a.txt.然后回车。编译成功。
这时目录下出现了一个a.exe的文件。点击执行,效果如下。
消息框弹出了。后面还有个黑框框。有人可能会问了,这里并没有什么/r /t的,为什么会成功呢?这就是默认的缘故。我们说了,/t默认为exe(控制台),/r默认引用了vbc.rsp里的程序集。所以可以成功。
好了,这里就不多讲了,大家可以自己看着参数摸索一下,很容易就会掌握了。
下面进入第三部分,vbnet的动态编译。
动态编译,即在代码中动态编译出程序。方法有很多,可以调用vbc,也可以使用反射,但我们这里使用一种较为简单的方法VBCodeProvider。
为使用,首先添加引用
Imports System.Reflection Imports System.CodeDom.Compiler
然后,声明VBCodeProvider对象。
Dim cp As New VBCodeProvider()
这样,就创建了一个vb编译器实例。
我们还要再声明一个参数对象。CompilerParameters
Dim cParameters As New CompilerParameters()
我就不放出CompilerParameters的成员列表了。大家可从http://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=ZH-CN&k=k%28System.CodeDom.Compiler.CompilerParameters%29;k%28TargetFrameworkMoniker-.NETFramework 查看。
这里讲一下它的几个重要的属性
1.GenerateExecutable 通过它可以设置是否编译成exe文件。我们这里为true。
2.GenerateInMemory 他可以指示是否在内存中生成输出。 这里为false。
3. OutputAssembly 用它来设置输出程序集的名称。
4.ReferencedAssemblies 获取本程序引用的程序集。可以通过ReferencedAssemblies的Add方法添加引用。
设置完了之后来上这一句获得编译结果
Dim cresult As CompilerResults = pc.CompileAssemblyFromFile(cParameters, "a.txt")
这就是说,用cParameters作为参数编译a.txt这个文件,返回编译结果给cresult
然后对cresult进行操作保存生成的exe,详见代码。
好了,用这个方法方法,我们用代码编译a.txt
我很懒,就直接写在form的load里面了。
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ‘声明 Dim pc As VBCodeProvider = New VBCodeProvider Dim cParameters As New CompilerParameters() cParameters.GenerateExecutable = True ‘生成exe文件 cParameters.GenerateInMemory = False ‘不在内存中生成 ‘添加引用 cParameters.ReferencedAssemblies.Add("System.dll") cParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll") ‘编译并返回结果 Dim cresult As CompilerResults = pc.CompileAssemblyFromFile(cParameters, "a.txt") If cresult.NativeCompilerReturnValue = 0 Then ‘如果编译成功 Try ‘避免重名而报错,删除旧文件 My.Computer.FileSystem.DeleteFile("a.exe") Catch ex As Exception End Try ‘把生成的文件移动到目标目录下(因为他是保存在一个特定的地方, 文件名也是随机的) My.Computer.FileSystem.MoveFile(cresult.PathToAssembly, "a.exe") Else For Each a As CompilerError In cresult.Errors ‘出错,显示错误信息 MsgBox(a.ErrorText) Next End If End Sub
这样,一个简单编译器就做好了。
标签:
原文地址:http://www.cnblogs.com/codepoetry/p/4229848.html