[C#學習筆記1]用csc.exe和記事本寫一個C#應用程序


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的最新版本及之前的版本。

.NET Framework Developer Pack下載地址

 

如果不想那么麻煩,可以直接安裝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路徑,就可以在這里直接使用了。

CMD

Developer Command Prompt for VS 2017

比如這里,輸入csc -?,窗口中顯示了C#編譯器的命令行參數列表;同樣地,輸入vbc -?,窗口顯示VB編譯器的命令行參數列表。其中,有些參數在我們用csc.exe編譯C#源文件時會用到。

C#命令行參數

VB命令行參數


一、編輯源程序

  在C盤新建一個文件夾test,在文件夾里創建一個記事本文件HelloWorld.txt。用記事本打開編輯這個文件,輸入C#代碼,注意輸入空格以縮進。之后將HelloWorld.txt后綴名改為HelloWorld.cs。*.cs是C#代碼文件的后綴名。

  用記事本編輯源文件

二、打開Developer Command Prompt,啟動csc.exe編譯源程序

  更換路徑到源程序所在文件夾下。

  更換路徑到源程序所在文件夾下

  輸入csc HelloWorld.cs,啟動編譯。

  編譯成功

  編譯成功,在test文件夾下,可以看到HelloWorld.cs已經被編譯成一個可執行程序HelloWorld.exe。

  源程序已經被編譯成了可執行程序

  HelloWorld

三、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,進行其他選項的測試。

  測試1

  此外,命令行輸出選項中的"/"符號還可以換成"-"符號。

  命令行選項中可以換一個符號

 

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

  修改源文件。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.Windows.Forms.dll是外部程序集,那什么又叫作“不是外部程序集”呢?查看System.dll程序集中的System命名空間的成員,發現並沒有我們使用的Console類。

  外部程序集System.dll中並沒有Console類

  這是因為,我們使用的Console.WriteLine()中的Console類所在的命名空間System,不是包含在System.dll中的!我們查看mscorlib這個程序集。

  mscorlib.dll

  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中可以看到程序集在磁盤中的路徑。

  mscorlib的路徑

  在Visual Studio中創建應用程序時會選擇.NET Framework的版本,因為例子中這個程序選擇的是.NET Framework 4.6.1,所以它引用的程序集就是磁盤中.NET Framework 4.6.1中的程序集。

  .NET Framework 4.6.1的程序

  .NET Framework 4.6.1文件夾

  進入這個文件夾,可以看到其中包含的程序集。我們看到mscorlib.dll這個程序集的容量很大,也反映出這個程序集的重要性。

  文件夾下的mscorlib.dll

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

五、編譯多個源文件

  現在我們已經可以使用csc.exe和記事本構建一個可以引用外部程序集的控制台應用程序了,但是我們所有的代碼都是寫在一個C#源文件中的。我們也可以將代碼寫在多個文件中,使用csc.exe對多個源文件進行編譯。

  在test文件夾下增加MyMessageBox.txt文件,之后要將后綴名改為.cs(下同)。

  增加MyMessageBoxtxt文件

  修改HelloWorld.txt文件。

  修改HelloWorldtxt文件

  打開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#學習筆記

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM