背景
最近在做一個Revit插件,需要做一個樹形清單,找了一圈後發現沒有比Devexpress更好用的控件,于是選用Devexpress的grid。
過程中遇到的問題及解決方案
安裝完Devexpress後,在項目引用管理器中可以看到Devexpress相關的程式集,引用以下幾個程式集後可以合用WPF版本的Grid
問題1:找不到程式集
在開發結束後,用InnoSetup對編譯目标的所有檔案進行打包,在開發機中安裝運作沒有問題,但放到未安裝DevExpress的機器上會報
找不到程式集
的異常,檢查了一下安裝目錄檔案,發現
DevExpress.Xpf.Themes.Office2016White.v17.1.dll
不存在
解決方法1
逐個檢查缺少的程式集,并在生成後事件中通過腳本把缺少的dll拷貝到目标檔案夾,但這種方法檢查成本高,不适用于頻繁變更的程式;
解決方法2
利用DevExpress提供的釋出工具把所需的依賴直接釋出到目标檔案夾
這種方法不用擔心丢失所需的dll,但該工具隻提供了可視化版本,無法通過腳本內建到項目中。
解決方法3
把所需的依賴項通過引用管理器添加到項目引用中,并讓它複制到本地,這種方法與方法一類似。
問題2:未實作該方法或操作異常
先看一下異常資訊
System.Windows.Markup.XamlParseException:
“設定屬性“System.Windows.Controls.ContentControl.Content”時引發了異常。”,行号為“22”,行位置為“6”。
---> System.Xaml.XamlObjectWriterException:
設定屬性“DevExpress.Xpf.Utils.Themes.ResourceDictionaryEx.Source”時引發了異常。
---> System.Windows.Markup.XamlParseException:
設定屬性“System.Windows.ResourceDictionary.DeferrableContent”時引發了異常。
---> System.NotImplementedException: 未實作該方法或操作。
找了一下StackOverflow,并沒有具體針對這這個異常提出的解決方法,得到的資訊是,出現XamlParseException有兩個可能原因:
- 多個資源使用了相同的key值
- 資源檔案找不到
結合
NotImplementedException
,基本可以推斷是Devexpress繼承并實作了WPF架構内的一些抽象類,并重寫了System.Windows.ResourceDictionary.DeferrableContent屬性,但目前程式無法加載該具體類,是以隻能報個NotImplementedException了。
解決方法
既然問題極大可能是無法加載程式集,那解決方案就明顯了,讓它能找到呗。而讓它找到最簡單粗暴的方法就是把需要的程式集加入到GAC了。
把程式加入GAC隻需要用到以下指令
gacutil /i [assembly].dll
測試機上嘗試了一下,手動把DevExpress的dll都注冊到GAC中,程式可以正常運作,驗證了該方法可行。
進一步完善
既然以上兩步可以解決DevExpress WPF構件的釋出問題,那麼接下來要做的就是把GAC注冊過程加入到安裝步驟中了。
1. 批量注冊GAC腳本
由于客戶機器上可能不存在gacutl.exe,是以首先我們要找到gacutil.exe,并把它打包一起釋出給客戶,gacutil.exe(注意,gacutil.exe.config也需要一起打包)位于路徑
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools
中,不同版本的vs對應的版本号可能不一樣。
使用以下腳本把DevExpress dll注冊到GAC
for /f "delims=" %%a in ('dir /b/a-d/oN Dev*.dll') do "%~dp0gacutil" /u "%%~na"
2. 把注冊過程寫入InnoSetup腳本中
[Files]
Source: "./gacutil.exe"; DestDir: "{app}";
Source: "./gacutil.exe.config"; DestDir: "{app}";這裡把gacutil加到安裝包内
;Run節點會在安裝結束後執行,這裡使用背景程序的方式執行上面的批處理腳本
[run]
Filename: "{app}\GacReg.bat"; Description: "Install.bat"; Flags: runhidden skipifdoesntexist
[/run]
3. 找一台機器進行測試
測試通過,方法可行。
存在問題
- Devexpress程式集的體積偏大,在本例中,實作業務邏輯的程式隻有不到1M,而DevExpress程式集有144M,雖然其中有大概60M的Theme程式程式集可以不打包進去,但這體積也還是太大了;
- 要不要在解除安裝過程中把GAC清理掉是一個問題,因為對于客戶機而言,把DevExpress留在GAC中并沒有必要,但如果删掉,萬一使用者有其他程式也引用了Devpexress,就會導緻誤删。