csc.exe是C#的命令行编译器(CSharpCompiler),可以编译C#源程序成可执行程序。它与Visual Studio等IDE(Integrated Development Environment,集成开发环境)的区别是,csc.exe只是将用C#语言编写的源程序文件编译成.exe、.dll等文件,它只是一个编译器,而IDE提供丰富的调试、运行功能,提供很多view视图以及解决方案管理器等文件组织功能。

csc.exe包含在.NET Framework SDK(Software Development Kit)中,除了csc.exe外,SDK还包括其他语言的编译器,如vbc.exe(vb语言的编译器)以及其他一些可能会用到的工具、文档等。.NET Framework SDK在微软官网可以下载,但现在好像包含在了.NET Framework Developer Pack(开发者包)里。https://www.microsoft.com/net/download。在这里可以下载.NET Framework和.NET Core的最新版本及之前的版本。

如果不想那么麻烦,可以直接安装Visual Studio,.NET Framework SDK(或Developer Pack)是自动随着IDE的安装而安装的。可以在这里下载免费的Visual Studio 2017社区版:https://visualstudio.microsoft.com/zh-hans/downloads/,也可以在这个页面下方选择安装之前的旧版本。

安装好SDK后,在磁盘中会多出很多.NET开发工具,其中一些工具需要在命令提示符中打开(Command,CMD)。但这些工具分散在各个文件夹下,需要为它们配置PATH环境变量,这样很麻烦。在安装好Visual Studio后,磁盘中会多出一个类似于CMD的命令提示符,叫作Developer Command Prompt for VS + VS的版本号。Developer Command Prompt预先配置了每一个.NET开发工具,不需要为它们注册PATH路径,就可以在这里直接使用了。

比如这里,输入csc -?,窗口中显示了C#编译器的命令行参数列表;同样地,输入vbc -?,窗口显示VB编译器的命令行参数列表。其中,有些参数在我们用csc.exe编译C#源文件时会用到。


一、编辑源程序

  在C盘新建一个文件夹test,在文件夹里创建一个记事本文件HelloWorld.txt。用记事本打开编辑这个文件,输入C#代码,注意输入空格以缩进。之后将HelloWorld.txt后缀名改为HelloWorld.cs。*.cs是C#代码文件的后缀名。

  

二、打开Developer Command Prompt,启动csc.exe编译源程序

  更换路径到源程序所在文件夹下。

  

  输入csc HelloWorld.cs,启动编译。

  

  编译成功,在test文件夹下,可以看到HelloWorld.cs已经被编译成一个可执行程序HelloWorld.exe。

  

  

三、C#编译器(csc.exe)的输出选项

  前面已经实现了用记事本编辑C#源程序并用csc.exe编译,最后在文件夹下可以成功打开编译而来的可执行程序。现在,考虑编译过程中的一些细节。

  源程序叫作HelloWorld.cs,编译后的程序叫作HelloWorld.exe。看上去没什么问题,其实编译后的程序的名字和类型是可以通过C#编译器的输出选项(参数)指定的。

  ①/out 规定编译后文件名字,如果不进行设置,编译后文件名与源程序名字相同  ②/target:exe 编译源程序成可执行的控制台程序,缺省选项  ③/target:library 编译源程序成*.dll程序集  ④/target:winexe 编译源程序成窗体程序 (其中/target可缩写成/t)

  所以之前在编译时,我们输入:csc HelloWorld.cs其实等价于输入:csc /target:exe /out:HelloWorld.exe HelloWorld.cs,只是中间两个选项都省略掉了。命令行选项和源文件的顺序是任意的,可以命令行选项在前,源文件在后。也可以源文件在前,命令行选项在后,甚至可以这样写:csc /target:exe HelloWorld.cs /out:HelloWorld.exe,这些都是可以的。

  打开Developer Command Prompt,进行其他选项的测试。

  

  此外,命令行输出选项中的"/"符号还可以换成"-"符号。

  

四、源程序中引用了外部程序集

  修改源文件。using System.Windows.Forms引入了一个命名空间,以使用其中的MessageBox类的静态方法Show(),弹出一个对话框显示相关内容。System.Windows.Forms命名空间存在于System.Windows.Forms.dll程序集中(命名空间与程序集名称相同)。源文件中使用了外部程序集的内容,csc.exe在编译时需要通过/reference命令行选项指定引用的外部程序集(/reference可缩写为/r)。

  

  下面进行编译,省略/target和/out选项。

  

  

  可能有读者在这里并没有/reference:System.Windows.Forms,而是直接csc HelloWorld.cs,也可以成功编译并运行,在后文会对这个问题进行解答。(C#默认响应文件csc.rsp的概念)

  这里还有一个问题,在源文件中,使用System.Windows.Forms命名空间中的MessageBox类,需要引入这个命名空间所在的程序集System.Windows.Forms.dll,那使用System命名空间中的Console类,为什么不引入System命名空间所在的程序集System.dll?

  这就涉及到了“外部程序集”中“外部”的概念。在Visual Studio中,引入System.Windows.Forms.dll程序集后,查看其包含的内容。可以看到Show()方法是MessageBox类的静态方法,MessageBox类是System.Windows.Forms命名空间中的成员,而这个命名空间又是System.Windows.Forms.dll程序集中的逻辑概念。下图中,左侧两个小黑方块中间用一杠连起来的那个符号就是程序集的符号,花括号的那个符号是命名空间的意思。

  

  System.Windows.Forms.dll是外部程序集,那什么又叫作“不是外部程序集”呢?查看System.dll程序集中的System命名空间的成员,发现并没有我们使用的Console类。

  

  这是因为,我们使用的Console.WriteLine()中的Console类所在的命名空间System,不是包含在System.dll中的!我们查看mscorlib这个程序集。

  

  Console类原来是mscorlib.dll程序集中System命名空间的成员。mscorlib(MicroSoft CORe LIBrary),相对于System.Windows.Forms等一些外部程序集来说,是.NET平台中核心的程序集,可以把它们理解成“内部的”程序集。所以回到之前的那个问题,使用mscorlib.dll程序集中命名空间中的成员,只要在源文件中使用using关键字引入所用成员所在的命名空间即可(也可使用成员的完全限定名),而不用在使用csc.exe编译时通过/reference命令行选项额外引入mscorlib.dll这个程序集。

  其实,在Visual Studio IDE里看这个问题,也是相通的。在我们新建了一个控制台应用程序后,在解决方案管理器中References下会自动引入一些外部程序集。(mscorlib不显示在其中,因为它不需要引入!)当需要使用MessageBox等一些没有自动被引入的外部程序集中的成员时,就需要我们手动右键References添加所用的程序集。而mscorlib.dll是在创建应用程序时就已经添加进来的程序集,不用额外引入。在IDE中是这样,在命令行提示符中使用csc.exe编译时也是这样。

  在Visual Studio中可以看到程序集在磁盘中的路径。

  

  在Visual Studio中创建应用程序时会选择.NET Framework的版本,因为例子中这个程序选择的是.NET Framework 4.6.1,所以它引用的程序集就是磁盘中.NET Framework 4.6.1中的程序集。

  

  

  进入这个文件夹,可以看到其中包含的程序集。我们看到mscorlib.dll这个程序集的容量很大,也反映出这个程序集的重要性。

  

  如果csc.exe需要引入多个外部程序集,在/reference:程序集1;程序集2 中用英文分号";"分隔即可。

五、编译多个源文件

  现在我们已经可以使用csc.exe和记事本构建一个可以引用外部程序集的控制台应用程序了,但是我们所有的代码都是写在一个C#源文件中的。我们也可以将代码写在多个文件中,使用csc.exe对多个源文件进行编译。

  在test文件夹下增加MyMessageBox.txt文件,之后要将后缀名改为.cs(下同)。

  

  修改HelloWorld.txt文件。

  

  打开Developer Command Prompt,编译这两个文件,注意依然要使用/reference引入使用的外部程序集。编译的多个文件之间用空格隔开。

  

  执行这个程序。

  

  此外,在使用csc.exe编译多个文件时,还可以使用通配符"*"表示编译当前目录下的所有指定后缀名文件。如:csc *.cs表示编译当前目录下所有.cs文件。

六、使用C#响应文件

  至此,我们已经可以使用csc.exe编译多个源文件的C#应用程序了。在编译过程中,需要设置一些命令行选项以达到某种效果。当程序规模大到一定程度,就需要输入很多的命令行选项,容易出错且录入工作量大。为了应对这一问题,C#有响应文件(response file,后缀名为rsp)的概念。C#响应文件包含编译一个或多个C#源文件时需要指定的命令行选项。

  编辑HelloWorld.rsp文件,将编译源文件时需要用到的引入外部程序集、设置输出程序的类型及名字等命令行选项写在这个文件里,并将这个响应文件和源程序文件放在同一目录下。csc.exe编译时,输入csc @HelloWorld.rsp就可以按照设置的命令行选项编译这个C#源程序了。

  

  

  程序可以正常运行。

  

  这里有几点需要注意的地方:①写在后面的命令行选项或响应文件的内容会覆盖掉前面的命令行选项或响应文件的内容(以后规定的为准!) ②/reference具有累加性,最终程序引用的外部程序集为各个地方(命令行选项和响应文件)规定的程序集的并集

七、关于C#默认的响应文件csc.rsp

  回到之前提到的那个问题,为什么即使没有使用/reference引入需要的外部程序集,程序也是可以成功编译并执行的?

  C#编译器(csc.exe)有一个与之关联的默认响应文件(csc.rsp),csc.rsp与csc.exe在同一目录下(我没有找到..)。在编译C#源程序时,无论有没有自己编写的响应文件,这个默认的响应文件csc.rsp都会执行。而csc.rsp已经写好了对很多核心程序集的引用(用/reference或/r命令行选项)。所以即使我们没有使用/reference引入外部程序集,csc.rsp也帮我们引入好了。

  如果不想在编译时自动执行csc.rsp,可以指定/noconfig选项。

  如果我们在编译时指定了/noconfig选项且没有使用/reference引入源文件中需要的外部程序集,那么编译将报错。

  

  如果程序引用了在源文件中没有用到的外部程序集(比如csc.rsp帮我们自动引入的),它们将会被编译器忽略,所以不会影响程序的质量。


返回目录:C#学习笔记

[C#学习笔记1]用csc.exe和记事本写一个C#应用程序的更多相关文章

  1. SpringBoot学习笔记(11):使用WebSocket构建交互式Web应用程序

    SpringBoot学习笔记(11):使用WebSocket构建交互式Web应用程序 快速开始 本指南将引导您完成创建“hello world”应用程序的过程,该应用程序在浏览器和服务器之间来回发送消 ...

  2. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(下)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  3. 一起学习造轮子(二):从零开始写一个Redux

    本文是一起学习造轮子系列的第二篇,本篇我们将从零开始写一个小巧完整的Redux,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Promises/A+,Red ...

  4. 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise

    本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...

  5. 一起学习造轮子(三):从零开始写一个React-Redux

    本文是一起学习造轮子系列的第三篇,本篇我们将从零开始写一个React-Redux,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Promises/A+,Re ...

  6. python学习(10)字典学习,写一个三级菜单程序

    学习了字典的应用.按老师的要求写一个三级菜单程序. 三级菜单程序需求如下: 1.深圳市的区--街道--社区---小区4级 2.建立一个字典,把各级区域都装进字典里 3.用户可以从1级进入2级再进入3级 ...

  7. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(中)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 四.创建一个Blazor应用程序 1. 第一种创 ...

  8. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(完)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  9. Python学习笔记:PyInstaller(exe程序打包)

    PyInstaller可以将Python程序打包成一个exe程序来独立运行,用户使用时只需要执行这个exe文件即可,不需要在机器上再安装Python及其他包就可运行了.另外,PyInstaller相较 ...

随机推荐

  1. Spring boot 继承 阿里 autoconfig 配置环境参数

    前提:基于springboot 项目 1. 配置pom.xml 文件 <plugin> <groupId>com.alibaba.citrus.tool</groupId ...

  2. 5.3Role和Claims授权「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢谢关注. Role授权 这是一种Asp.Net常用的传统的授权方法,当我们在 ...

  3. 我爱Java系列之《JavaEE学习笔记day12》---【缓冲流、转换流、序列/反序列化流、打印流】

    [缓冲流.转换流.序列/反序列化流.打印流] 一.缓冲流 1.字节缓冲输出流 java.io.BufferedOutputStream extends OutputStream 高效字节输出流 写入文 ...

  4. SpringBoot | 第六章:常用注解介绍及简单使用

    前言 之前几个章节,大部分都是算介绍springboot的一些外围配置,比如日志配置等.这章节开始,开始总结一些关于springboot的综合开发的知识点.由于SpringBoot本身是基于Sprin ...

  5. 5.App Inventor 2编程实例--指南针

    本视频来自:https://www.17coding.net 的  国庆特辑——指南针 共3个视频. 注意: 项目名字要使用英文. 项目完成后可以选择“打包APK”—“ 打包APK并下载到电脑”,然后 ...

  6. 千星项目.Net Core 2.1移植填坑记--OpenAuth.Core诞生

    背景 很早就有把OpenAuth.Net----最好用的.net权限管理工作流框架(好吧!我在吹牛

  7. 【死磕 Spring】----- IOC 之 获取验证模型

    原文出自:http://cmsblogs.com 在上篇博客[死磕Spring]----- IOC 之 加载 Bean 中提到,在核心逻辑方法 doLoadBeanDefinitions()中主要是做 ...

  8. git的学习笔记(二):git远程操作

    1.创建ssh key ssh-keygen -t rsa -C "your_email@example.com" 执行命令后会在用户的家目录生成.ssh的隐藏文件夹,文件夹里有公 ...

  9. .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划

    作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9977862.html 写在前面 千呼万唤始出来,首先,请允许我长吸一口气!真没想到一份来自28岁老程序员 ...

  10. Vue基础(环境配置、内部指令、全局API、选项、内置组件)

    1.环境配置 安装VsCode 安装包管理工具:直接下载 NodeJS 进行安装即可,NodeJS自带 Npm 包管理工具,下载地址:https://nodejs.org/en/download/安装 ...