自己动手制作CSharp编译器
在你喜欢的位置(如F盘根目录)新建一个文件夹,并命名为“CSharp开发环境”。找到或下载C#编译器组件(csc.exe和cscui.exe),并放在先前建立的文件夹中。该组件的一般位置在C盘的.NET文件夹中,如“C:\Windows\Microsoft.NET\Framework\v4.0.30319”,最后一个为版本号,可根据你的需要选择。同时在这个文件夹中还有我们需要的类库(System.dll),找到并复制到“CSharp开发环境\lib”文件夹中。
- 2
为了能够在控制台下找到我们的编译器,下面设置环境变量Path。右击桌面的计算机->点击属性->点击高级选项卡中的环境变量->在用户环境变量选中Path并点击编辑->添加“F:\CSharp开发环境;”->点击OK即可。如下图:

- 3
测试。打开控制台(如果你用到是Win8,可以 Win+X ->C 快速打开控制台),并输入csc,若出现下图结果即表示正常。
END
编写代码
- 1
在你喜欢的位置(例如,“F:\CSharp开发环境\project”目录)中建立一个文件夹,并命名为“cc”,该目录便是我们存放源代码的目录。
- 2
添加源文件。在cc目录中新建“cc.cs”文件,并用文本编辑器打开,并输入以下代码:
using System;
using System.IO;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
namespace CC{
public class CC{
public static void Main(string[] args){
if(args.Length==0){
Console.WriteLine("该工具的正确使用方法是:cc 源文件");
Console.Read();
return;
}
FileInfo sourceFile=new FileInfo(args[0]);
CodeDomProvider provider=null;
if(sourceFile.Extension.ToUpper()==".CS"){
provider=CodeDomProvider.CreateProvider("CSharp");
}
else if(sourceFile.Extension.ToUpper()==".VB"){
provider=CodeDomProvider.CreateProvider("VisualBasic");
}
else{
Console.WriteLine("错误1:源代码文件必须以“.cs”或“.vb”为后缀");
}
if(provider !=null){
string exeName=String.Format(@"{0}\{1}.exe",Environment.CurrentDirectory,sourceFile.Name.Replace(".","_"));
CompilerParameters cp=new CompilerParameters();
cp.GenerateExecutable=true;
cp.OutputAssembly=exeName;
cp.GenerateInMemory=false;
CompilerResults cr=provider.CompileAssemblyFromFile(cp,args[0]);
if(cr.Errors.Count > 0){
Console.WriteLine("Errors building {0} into {1}",args[0], cr.PathToAssembly);
foreach(CompilerError ce in cr.Errors)
{
Console.WriteLine(" {0}", ce.ToString());
Console.WriteLine();
}
}
else
{
Console.WriteLine("Source {0} built into {1} successfully.",args[0], cr.PathToAssembly);
}
}
Console.Write("Press any key to exit...");
Console.Read();
}
}
}
- 3
代码解释。
前5行代码是名称空间的引用,我们使用的最重要的类便在System.CodeDom.Compiler中。
6-8行分别定义名称空间、类和入口函数。
9-13行是对命令行参数的检验,为了简单,本文设定只有第一个参数有效,并且便是源文件名。
14-15行定义两个非常重要的变量,一个表示源文件的变量sourceFile(FileInfo),其参数从上一步中得到,即命令行第一个参数。另一个表示编译器的变量provider(CodeDomProvider,使用CompileAssemblyFromFile方法即可把源文件编译成目标文件),并初始化为null。
17-25行使用“工厂模式”得到CodeDomProvider的实例,即根据后缀初始化为VB编译器还是C#编译器。注意:本文只考虑C#代码,若您还想编译VB代码只需添加相应的引用即可。
27行是对provider的检验,若不为空则则可以继续编译。这是避免空引用异常的常用方法。28-34行定义编译选型,即CompilerParameters类。GenerateExecutable=true表示生成可执行文件,若为false表示生成类库;OutputAssembly表示生成的文件。
35行调用provider.CompileAssemblyFromFile(编译选项,源文件)方法生成可执行文件,并得到CompilerResults类的一个实例,该实例表示编译结果。
36行以后是对编译结果的处理,若有错则输出错误,若成功则提示生成成功。
- 4
编译。我们可以在命令行下直接编译,而为了在调试时不必重复输入相同的命令,我们可以做一个批处理。新建文本文件并重命名为“MakeFile.bat”,添加如下代码:
csc cc.cs /reference:%Lib%\System.dll
pause
然后双击运行,若没有错误的话就会得到“cc.exe”文件。
注意:为了方便的引用类库,我们需要添加环境变量,“Lib=F:\CSharp开发环境\lib”,注意这里没有分号而且只有这一个值(这是为了在写批处理文件时方便采这么设定的)。
END
测试
为了测试我们做的“编译器”,我们在project目录中添加hello工程(一个文件夹),并添加源代码文件“hello.cs”,hello.cs的内容为:
using System;
namespace Test{
public class Test{
public static void Main(string[] arg){
Console.WriteLine("Hello world");
Console.ReadLine();
}
}
}
然后,我们把得到的cc.exe文件复制到当前目录中。 同样的,我们也建立一个“MakeFile.bat”文件,代码如下:
cc hello.cs
pause
双击该批处理,若没有错误的话即可得到一个可执行文件(hello_cs.exe),如下:

- 2
执行“hello_cs.exe”文件,如图:

自己动手制作CSharp编译器的更多相关文章
- 市面上有没有靠谱的PM2.5检测仪?如何自己动手制作PM2.5检测仪
市面上能买到的11中常见的pm2.5检测仪 网上大佬实测并不是很准,我这里没测过(全买下来有点贵,贫穷限制了我的想象力) 这些检测仪多数是复合式.多功能的空气质量检测仪.具体就不一一介绍了.这篇文章 ...
- springboot2.x基础教程:动手制作一个starter包
上一篇博客介绍了springboot自动装配的原理.springboot本身有丰富的spring-boot-starter-xx集成组件,这一篇趁热打铁加深理解,我们利用springboot自动装配的 ...
- 自己动手,制作真正的.net Framework 3.5 SP1离线安装包(转)
.NET Framework 3.5 SP1发布了,兴冲冲…下载,当然是完全离线安装包.net Framework 3.5 Service pack 1(Full Package) 231MB,网络慢 ...
- 虚拟机Parallels Desktop 17 (PD17)支持M1 自己动手制作启动器解锁
个人博客:xzajyjs.cn 如果自己有能力的话,直接查看这个视频即可.点此 前段时间刚出pd17,作为mac上最最强(没有之一)的虚拟机,版本17更是更进一步,性能提升极大,更是支持了Monter ...
- 自己动手写一个编译器Tiny语言解析器实现
然后,上一篇文章简介Tiny词法分析,实现语言.本文将介绍Tiny的语法分析器的实现. 1 Tiny语言的语法 下图是Tiny在BNF中的文法. 文法的定义能够看出.INNY语言有以下特点: 1 程序 ...
- 动手制作属于你自己的WIN PE3.0
最近想要更新公司的网Ghost系统,所以小研究一下win pe ,在网上看见一个很不错的教程,在这里分享给大家! 并非原创,纯属转载!!O(∩_∩)O~天缘的作品,很是佩服这个哥们啊..... 一.W ...
- 自己动手制作一个本地的yum仓库
制作本地yum源有两种方式,第一种是使用光盘镜像,然后在本地进行安装.第二种是我们自己创建一个本地yum仓库,然后使用file的形式来向本地提供yum repo(也可以使用http的方式向外部提供,我 ...
- 自己动手制作更好用的markdown编辑器-01
这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im 文章目录 1. 简介 2. 项目结构 3. 程序主界面 4. 拖动窗口 5. app ...
- Android程序猿自己动手制作.9.png图片
1:怎样制作9.png图片素材: 打开SDK工具文件夹下: draw9patch.zip 解压执行draw9patch.bat.有的直接搜索会有:draw9patch.bat. 双击执行后,例如以下 ...
随机推荐
- hdu 2062
ps:11版的最后一题...是个递推题...比如n=5,推出首数字后,n--,继续找下一个 代码: #include "stdio.h" ]; ]; int main(){ lon ...
- POJ 3067 原来是树状数组--真的涨姿势
题意:计划在东边的城市和西边的城市中建路,东边的点从1.....n,西边的点从1......m,求这些点连起来后有多少个交叉. PS:这个题目没有任何思路,没想到是树状数组.... 交叉出5个点 分析 ...
- BackTrack5-r3安装VMware Tools
bt login:root //默认的BT系统账号password:toor //默认的BT系统密码,这里的密码是不显示的.root@bt:~#startx //进入图形模式 启动BT虚拟机系统-在V ...
- php 使用 curl 发送 post 数据
作为第三方开发商,经常会需要调用平台接口,远程调用,就要用到curl,其实质就是叫调用的方法与用到的参数以http post的方式发送至平台服务器. 简单的例子: $url = 'http://'; ...
- Where与Having的区别
地球人都知道,Where关键字的作用是过滤,选取符合条件的记录,而Having关键字的作用则是,为聚合结果指定条件.但是,在某些条件下,使用这两者可以得到一样的结果. 比如以下的例子: ) FROM ...
- 必须掌握的八个cmd 命令
一,ping 它是用来检查网络是否通畅或者网络连接速度的命令.作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它 所利用的原理是这样的:网络上的机器都有唯一确定的I ...
- declaration is incompatible with "__nounwind __interwork __softfp unsigned long __get_PSP(void)" IAR 编译报故障
原因是以前的CMSIS CORTEX-CM0 文件太老了. 使用新文件就可以.
- SqlServer不能将text列类型更改为ntext的问题
可以先将text类型更改为nvarchar,在将nvarchar更改为ntext即可. alter db_note alter column [content] nvarchar; alter db_ ...
- day27_反射
1.反射-概述(掌握) 反射就是在程序运行过程中,通过.class文件动态的获取类的信息(属性,构造,方法),并调用 注意:JAVA不是动态语言,因为动态语言强调在程序运行过程中不仅能获取并调用类里面 ...
- 帝国cms内容批量替换
方法一:栏目-其他相关-批量替换字段值 方法二:通过sql替换 UPDATE phome_ecms_news SET body=REPLACE(body,'原来','现在')