-
在你喜歡的位置(如F盤根目錄)新建一個文件夾,並命名為“CSharp開發環境”。找到或下載C#編譯器組件(csc.exe和cscui.exe),並放在先前建立的文件夾中。該組件的一般位置在C盤的.NET文件夾中,如“C:\Windows\Microsoft.NET\Framework\v4.0.30319”,最后一個為版本號,可根據你的需要選擇。同時在這個文件夾中還有我們需要的類庫(System.dll),找到並復制到“CSharp開發環境\lib”文件夾中。
-
為了能夠在控制台下找到我們的編譯器,下面設置環境變量Path。右擊桌面的計算機->點擊屬性->點擊高級選項卡中的環境變量->在用戶環境變量選中Path並點擊編輯->添加“F:\CSharp開發環境;”->點擊OK即可。如下圖:
-
測試。打開控制台(如果你用到是Win8,可以 Win+X ->C 快速打開控制台),並輸入csc,若出現下圖結果即表示正常。
END
編寫代碼
-
在你喜歡的位置(例如,“F:\CSharp開發環境\project”目錄)中建立一個文件夾,並命名為“cc”,該目錄便是我們存放源代碼的目錄。
-
添加源文件。在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();
}
}
}
-
代碼解釋。
前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行以后是對編譯結果的處理,若有錯則輸出錯誤,若成功則提示生成成功。
-
編譯。我們可以在命令行下直接編譯,而為了在調試時不必重復輸入相同的命令,我們可以做一個批處理。新建文本文件並重命名為“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),如下:
-
執行“hello_cs.exe”文件,如圖:
-