版本控管很重要!
沒有Source又要修Bug,.NET Reflector + Reflexil 是可以參考的解決方式。
【此篇文章主要是記錄下使用.NET Reflector + Reflexil 來修改Visual Studio 發行之dll檔】
為什麼會使用到.NET Reflector + Reflexil ? 當然是有故事的。
客戶拿公司提供的報表與API產出的報表要對帳,然後發生帳對不起來,因該專案已是多年案子,客戶起始需求也已難以考究。
解決方向大致是:
1.先從資料面確認是否是因為資料髒掉導致API產出的報表有問題,但資料面看起來沒什麼怪怪的地方
2.從SVN取得Source Code後追查API產生報表的邏輯,發現...沒有問題啊! 程式邏輯就是如此! 當然這不是解,哈哈!
拿起該專案的的API規格書(看起來應該是吧),開始確認文件上的說明,為什麼文件與Web Service不同支,目前SVN上的版本怎麼會跟正式機上的不一樣耶SVN上又有2個版本,一是該專案客製化版本、二是目前公版的版本,要調整程式也必須知道目前線上的系統是哪個版本吧,將正式機的版本取回並使用ILSpy這套軟體將dll檔反編譯後對照目前SVN上的所有版號,並找出最接近正式機上的版號來修改。
雖然找出最接近的版本,但公版與正式機上的還是有很大落差的,倘若要整包比對並修正會讓原本只要半天Trace邏輯+修正的工項變成,工時要200人天的開發案 (200人天是我亂講的,意思就是成本太高...)
原先認為客戶只有在使用API,站台網頁的部分沒有在使用,所以我只要修好API就能了結這一個工項,不過前輩這兩個字真不是叫假的(雖然平時沒有以前輩尊稱,但我內心可是尊敬的),用最相似的公版Code且只調整API邏輯的解法,必須是站台已沒有人在使用,將正式機的log拿回來一看,站台果然還有使用者。
(Egan的內心小劇場:差9元 我給你10元,工項跳過可以嗎XD)
其實主要就是早期專案維運要調整程式,但又沒有正式機上的Source Code,隨意拿相似的版本上版一定會擴大問題(E Method調整好,而A、B、C、D全數死去) ,在這樣的情況下可以嘗試使用以下工具來進行程式的調整
.NET Reflector + Reflexil
.NET Reflector是套付費軟體,它是一套.NET反組譯工具
我們可以將Reflexil Add 到.NET Reflector裡面使用,然後再對要調整的程式碼進行修改:
1.將Reflexil Add 到.NET Reflector
2.將要調整dll拉至.NET Reflector,找出要修改的地方再透過Reflexil 進行調整
參考下圖,可以看到.NET Reflector會列出該WebService1.asmx這支裡面提供的兩支Service
如果我要修改Egan這支Method,我只要在.NET Reflector點選該Method(綠色方框),接著點選Tools > Reflexil,然而就會叫出Reflexil
接著在Reflexil的框框內點擊右鍵,選取Replace with all Code...
(當然可以調整il來對程式進行微調,但Egan還不會寫中繼語言,我願意為了這個功能調整而學習il,可以給我200天的工時嗎? << 欠揍)
接著就能直接開始對該支Method「重寫」,如果只是微調可以將原本的Code貼上(上圖的 複製我),參考下圖:
可以在藍色框內加入要Using ,紅色框就是要調整的部分,程式修改後在按下「Compile」看看是否編譯成功,如果失敗的話大多應該是找不到命名空間導致(試了幾次都是這樣)
「Compile」成功後按下OK,接著參考下圖,選到修改的dll>右鍵>Reflexil>Save as...
這樣就能將改好的dll蓋上測試了。
這樣的解法算是很不得已的解法,但如果像是我們這一個Team會常碰上古時代的專案且可能還會有遺失Source Code的問題,這個方法倒是可以參考看看,畢竟維運與功能重作成本是有很大落差的。(4小時與200小時 50倍!!!)
針對這個方式有寫一個小網頁進行測試,測試情境包含:
1. 修改後的Method是否正確
2. 修改了asmx是否影響到其他aspx頁面
3. asmx包含A、B兩支Method,修改了A是否影響了B
4.方案內的「專案WebApplication1」參考了「專案ASMX.Service」 ,在Reflexil 進行WebApplication1專案程式的調整時,是否能叫用專案ASMX.Service的類別
以上情境測試結果為正確,目前只是回家自行研究,尚未直接針對該工項進行調整,是否能成功還不確定,畢竟自己寫的測試Code並無正式機上更多複雜的參考其他專案或套件
目前只是做簡單的測試,其他較深入的功能可能就要再行研究了。
egan2608@gmail.com