本篇文章內容包括基礎知識(GAC、程序集強簽名、友元程序集)、編譯過程、注冊GAC、添加工具箱、多語言支持、運行時和設計時調試
編譯環境
工具:Visual Studio 2010
源碼:DXperience source code14.2.3.14339(源碼已經整理好,不需要任何改動,解決方案文件放在sln\WinForm\WinForm.sln)
源碼結構

為了更好地驗證最后的編譯成果,如果已經安裝了DevExpress官方版,請先卸載,編譯DevExpress的源碼並不依賴於DevExpress官方版的安裝。
編譯目標
1. 將DevExpress中WinForm相關組件全部編譯
2. 編譯完成后能手工添加到工具箱
3. 從工具箱中拖放控件到Form中,設計視圖能正常工作,運行時也正常。
4. 提供多語言支持
5. 能調試運行時和設計時
編譯基礎
在動手編譯之前,先復習一下基礎知識
GAC
1. 什么是GAC
GlobalAssembly Cache,全局程序集緩存
2. 為什么要注冊GAC
注冊到GAC中的程序集能被整個系統共享
3. 如何注冊及取消注冊
使用.net framework自帶的工具gacutil
gacutil/i [abc.dll],將當前目錄下的abc.dll文件注冊到GAC
如果要注冊的文件比較多,可以使用列表文件,后面在DevExpress源碼編譯完成后,生成的文件比較多,可以使用批量注冊,命令為gacutil /il list.txt,其中list.txt的格式如下:
DevExpress.BonusSkins.v13.2.dll
DevExpress.Charts.v13.2.Core.dll
DevExpress.CodeConverter.v13.2.dll
……
每行一個文件名
取消注冊與注冊類似,可以參考.net framekwork工具幫助
程序集強簽名
1. 什么是程序集強簽名
在生成程序集時,指定一個私鑰文件(該私鑰文件為私有,不會對外公開),經過這樣的方式編譯后的程序集稱為強簽名程序集。
2. 為什么要使用簽名
l 保證生成的程序集唯一性,強簽名的程序集都有一個公鑰,只有用特定私鑰生成的程序集才會有該公鑰。
l 防止程序集被非法篡改,一旦強簽名后,程序集內部會保存公鑰,加載該程序集時,CLR會驗證該公鑰,如果被非法篡改,則公鑰驗證失敗,會拋出異常。
l 未簽名的程序集無法注冊GAC
3. 如何使用簽名
l 生成私鑰(PS:這個私鑰只是演示用,源碼中使用的並不是這個私鑰)
使用.net framework工具sn,sn -k MyKey.snk,生成的私鑰文件存放在當前目錄下的MyKey.snk


l 查看公鑰
首先將公鑰寫入文件


然后再查看公鑰

4. 在VS中指定簽名
在VS中指定簽名至少能通過兩種方式
一、 在AssemblyInfo.cs文件中指明簽名文件路徑

二、 在工程屬性欄中的“簽名”標簽

以上兩種方式任選其一,第二種方式在VS2005之后才支持,現在DevExpress推薦采用第二種,我們的源碼中簽名全部采用這種方式。
5. DevExpress的簽名
DevExpress公司在發布產品時,使用了私鑰對產品進行了強簽名,目前只知道其公鑰標記為b88d1754d700e49a,如果你的程序加載的程序集公鑰為b88d1754d700e49a,則證明使用的是DevExpress公司提供的,而不是其它人提供的
6. 源碼中的簽名
在編譯源碼前,需要生成我們自己的私鑰,生成的私鑰放在DevExpress.Key文件中,解決方案中所有的工程都使用該簽名,這里可以看一下我們的公鑰

這也就意味着,我們編譯出來的程序集公鑰標記為94a041a7af35fb7f,其它任何人都無法仿制與篡改。(PS:這個公鑰可以到src\DevExpress.Key\key.txt文件中找到)
友元程序集
1. 什么是友元程序集
默 認情況下,程序集里使用internal修飾符,則該類型或成員只能在該程序集內部訪問,如果需要讓外部也能訪問到,這就需要友元程序集。[MSDN]友 元程序集是一種能夠訪問其它程序集的internal類型和成員的程序集,如果將程序集指定為友元程序集,則不再需要將類型和成員標記為公共,以使其他程 序集可以訪問它們
2. 為什么需要友元程序集
l 單元測試,測試代碼在另一個程序集運行,但需要訪問正在測試的程序集internal成員
l 類庫分開在多個程序集中,程序集需要互相訪問內部internal成員
3. DevExpress中的友元程序集
DevExpress中很多的基礎功能放在DevExpress.Data中,該程序集有很多友元程序集,打開DevExpress.Data下的AssemblyInfo.cs,可以清楚地看到它的友元程序集

即,在以上這些模塊中,可以直接訪問DevExpress.Data中的internal類型。
其它模塊的友元程序集與DevExpress.Data類似。
編譯過程
1.
代碼獲取
代碼已經全部打包成壓縮文件
2.
修改簽名
私鑰已經生成好,工程已經使用該私鑰簽名,不需要修改。如果想使用自己的簽名,需要按照以下步驟:
一、 使用.net framework自帶工具生成一份強簽名文件,名稱為StrongKey.snk,覆蓋src\DevExpress.Key下的同名文件
二、 打開sln\WinForm\WinForm.sln,在整個解決方案中,替換所有引用公鑰標記和公鑰的地方


3.
編譯
打開sln\WinForm\WinForm.sln,然后重新生成解決方案
后續工作
注冊
GAC
生成后的部分文件如下:

另外Design文件夾中包含了需要設計時支持的程序集,將生成的這些DLL文件注冊進GAC中(如何使用列表批量注冊,可參考前文),Design中的DLL也要注冊。
工具箱添加
打開VS,新建一個WinForm項目,打開工具箱,空白處右鍵,選擇“添加選項卡”

然后自己輸入一個名稱,這里取名為“DevExpressBuild”,然后右鍵,選擇“選擇項”

在彈出的對話框中選擇“瀏覽“,然后選擇GAC中某個DevExpress DLL,這里以ChartControl為例,選擇C:\Windows\Microsoft.NET\assembly\GAC_MSIL \DevExpress.XtraCharts.v14.2.UI下的文件夾下的DLL。確定后,能看到工具箱添加成功,如下:

其它控件工具箱的添加過程類似。(PS:此處有人有疑問,你怎么知道ChartControl放在DevExpress.XtraCharts.v13.2.UI這個DLL文件中,關於具體的控件放在哪個DLL中,DevExpress自帶的文檔都有詳細的說明,請參考)
成果檢驗
至此,DevExpress的編譯已經完成,下面來檢驗編譯后的成果。
還是上面的工程,直接拖放工具箱中的ChartControl到窗體中,終於看到自己編譯的成果了

隨便選擇一種類型,點擊“Finish”,注意看VS中的引用列表

已經自動為我們引用了所需的DLL,在部署時,只需要將這些DLL打包部署到客戶機器上即可。
已經很接近完美了,下面看看多語言支持
多語言支持
如 果使用的是安裝版的DevExpress,可以到官方網站下載所需的資源文件,但是我們是自行編譯的,無法直接使用官方提供的強簽名的資源文件。這就需要 我們自行編譯語言的資源文件了,這個編譯也很簡單,因為解決方案全部設置好了(如果源碼編譯時使用了自己的簽名,需要將 src\DevExpress.Key\StrongKey.snk拷貝到 dxKB_A421_DXperience_v14.2_(2014-12-16)\DevExpress.Key\下覆蓋同名文件),只需要打開 dxKB_A421_DXperience_v14.2_(2014-12-16)\Localization.sln,重新生成,生成的產物路徑為 dxKB_A421_DXperience_v14.2_(2014-12-16)\DevExpress.Dll,假如我們需要控件支持漢語,則進入 DevExpress.DLL\zh-CN,將文件夾里面所有的DLL注冊進GAC
關閉並重新打開剛才新建的工程,在剛才創建的ChartControl基礎上,創建一個Ribbon,可以看到,界面已經漢化了。

雖然官方提供的資源漢化率不是100%,但在運行時已經基本能滿足要求了。
源碼調試
運行時調試
既然通過源碼編譯的,那么調試應該不是什么大問題了
例如上面的工程中,我想在運行時,向圖表中添加一個點,我想看看這個點的添加過程

AddPoint事件處理代碼只有一句

在DevExpress.XtraCharts.UI工程中的ChartControl.cs文件中Series
屬性添加斷點,如下

然后調試工程,點擊“AddPoint”按鈕,命中了斷點

其它的調試都是類似過程。
設計時調試
DevExpress 控件對VS設計時支持得很好,在設計階段,可以非常直觀地設置控件屬性。如果想了解DevExpress在設計時做了哪些事情,可以對設計時進行調試。設 計時調試與運行時調試不太一樣,設計時調試實際上是使用一個VS調試另一個VS,這里我們舉一個例子,我想看看上面這個ChartControl控件在設 計時,點擊“關於”時做了哪些事情

一、 首先在工程屬性中,選中“調試”標簽頁,啟動操作選擇“啟動外部程序”,后面的路徑選擇VS2010所在的路徑,默認為C:\Program Files(x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe,也即我想調試另外一個VS
二、 添加斷點
這 一步斷點的位置根據自己的需求,本次我們的斷點設置在DevExpress.XtraCharts.Design工程中的Designers.cs文件中 的ChartControlDesigner類中的OnAbout方法,如下(PS:此處有人有疑問,你怎么知道點擊“關於”后進入這個函數的,實際上, 調試代碼前,需要大概了解代碼)

三、 開始調試
F5啟動調試,這時會打開另一個VS,在這個新的VS中打開剛才的工程,點擊窗體上ChartControl控件右側小箭頭,在彈出的界面中選擇“關於”,VS果斷命中斷點,如下

實際上官方提供的14.2.3安裝版里的ChartControl控件點擊“關於”是沒有任何反應的,這段代碼是我自己加上的,也是起作用的,彈出的對話框如下

這就是傳說中設計時調試,注意,此時應用程序並沒有運行起來,這種調試方式對於開發自定義控件非常有用
Q&A
Q
:工具箱中拖放控件到
Form
中,沒有反應或者提示各種錯誤
A:這種情況一般都是因為沒有注冊生成目錄中Design文件夾下的以”.Design.dll”為結尾的文件,要想在VS中對控件進行設計,這些DLL必須注冊到GAC
Q
:以
.Design.dll
為結尾的文件,在部署時,需要拷貝到客戶機器上嗎?
A:不需要,這些DLL在運行時不需要
Q
:從工具箱中拖放一個控件到
Form
中,如何讓
VS
自動引用所需的
DLL
A:將依賴的DLL注冊到GAC
Q
:使用源碼編譯后的程序集還需要破解嗎?
A:不需要,在工程引用中,引用的DLL文件屬性中,“復制本地”設置為true,然后將輸出目錄中的文件進行打包,拷貝到其它機器即可