背景:
一同事提到某客戶要求修改產品程序中的一段文字婿屹,正常情況下這是很簡單的事情鸭你,不需要我這業(yè)余人員參與,但問題在于該客戶使用的是舊版本產品剩胁,而舊版本產品的代碼已遺失诉植,這種情況下修改文字就成了一個棘手的工作。幾經輾轉這個事情就找到了我這里昵观,受不了同事再三托付晾腔,我答應其試試舌稀。
該程序使用.net 2.0開發(fā)。
目的:
需要修改的為一C/S客戶端界面灼擂,在界面中某個label處(假設原文字為“服務器123壁查!”)增加一段文字描述(假設為“新增服務器”),使程序可正常運行剔应,兼顧美觀性睡腿。
工具手段:
google、UE峻贮、.Net Reflector8.1席怪、ildasm、.net framework2.0纤控、自編漢字轉碼工具(javascript)
準備工作:
利用google下載上面提到的幾個工具挂捻,并掌握各個工具的使用方法,我這里大概說說各個工具的用途:
.Net Reflector8.1很有用的工具船万,可以查看.net編譯程序的源碼格式刻撒,用于了解程序的編制思路及尋找修改方式;
ildasm.exe可以將.net編譯的可執(zhí)行程序(dll唬涧、exe)反匯編為il中間格式疫赎,該格式可使用ue進行編輯修改盛撑;
UE我喜愛的工具碎节,全稱ultraedit,超好用的文本編輯工具抵卫,支持hex格式編輯狮荔;
.net framework2.0我們修改后的il文件需要依托.net framework2.0進行再次編譯,才能形成可執(zhí)行文件介粘,其實主要使用ilasm.exe;
自編漢字轉碼工具殖氏,這個是我為了方便自己寫的轉換工具,做得事情不復雜姻采,主要是將字符尤其是中文轉換為unicode編碼雅采,再將unicode編碼轉換為il文件中的中文編碼(去掉\u、將雙字節(jié)的高低位互換)慨亲;大家也可以手工轉婚瓜,在網上搜索unicode在線編碼轉換將字符轉換unicode編碼,手工去掉\u刑棵,再將雙字節(jié)高低位互換巴刻。(我會單獨寫文章把這個工具與大家共享的)。
因為不確定客戶使用的哪個小版本產品蛉签,所以我讓同事從客戶處把程序直接拷貝給我了胡陪。
修改步驟
相關準備工作做完后就要開戰(zhàn)了沥寥。
1、首先出場的當然是.Net Reflector8.1了
將需要修改的程序文件(如果有多個文件不確定是哪個的話就需要都托付給reflector反編譯先)柠座,通過Reflector查找文字“服務器123邑雅!”,這樣可快速定位這個界面的源碼位置妈经,通過讀源碼我們知道了這個界面上有哪些控件蒂阱,哪些控件與我們待修改的內容有關。
2狂塘、輪到二號人物出場了ildasm.exe
打開ildasm.exe录煤,將待修改的程序文件拖放到該程序,選擇轉存為123.il文件荞胡,轉存時注意選擇utf-8編碼妈踊,關鍵人物的出場都是短暫的,短暫但確很重要泪漂。
3廊营、三號人物UE出場
使用UE打開123.il,這個地方我走了我彎路萝勤,在UE中直接找中文“服務器123露筒!”,找了N遍都沒有敌卓,后來google了很久慎式,找到有專家說要轉成unicode編碼,到網上找工具將服務器123趟径!轉成了unicode編碼瘪吏,直接按照轉換的16進制搜索,還是找不到蜗巧,當時俺那個崩潰呀掌眠,心想難道不在123.il,后來又查找123.res(也是ildasm.exe的產物)幕屹,但都是徒勞無貨蓝丙。后來在UE和reflector中反復走查代碼,俺終于發(fā)現(xiàn)了規(guī)律望拖。原來il文件中又對unicode編碼進行了雙字節(jié)高低位互換渺尘,這個折磨人的編碼問題呀。還是給同學們展示個實例吧:
中文:服務器unicode編碼:\u670D\u52A1\u5668il編碼:0D 67 A1 52 68 56
4靠娱、編寫漢字轉換工具
我比較懶或者說不喜歡做重復工作沧烈,我一想到要一個一個漢字的轉編碼、調順序像云,而且客戶要加的文字還不少锌雀,那個頭疼啊蚂夕。一怒之下為配合三號人物完成工作俺連夜編寫了一個html頁面(使用javascrip腳本)用于轉換漢字編碼,好久不寫代碼了腋逆,N多生疏婿牍,心里默默感激google與大眾的分享,讓俺能完成這個小小工具惩歉。
5等脂、UE繼續(xù)出場
工具有了就好辦多了,首先通過工具將原始文字“服務器123撑蚌!”轉換為il編碼(暫且這么叫吧)上遥,在UE中查找,OK一查即中争涌,鼠標停留在字符串結束位置粉楚,將待增加文字“新增服務器”轉換為il編碼,直接在UE中粘貼即可(服務器123亮垫!之后)模软,這樣文字修改就可以了。
6饮潦、.net framework2.0出場
第五步我們只是把程序中間格式文件修改好了燃异,但還不是可執(zhí)行程序,要編譯出.net 2.0的程序當然還得使用它本身了继蜡,但il的編譯需要使用的是ilasm.exe回俐。
該命令需要在cmd窗口中執(zhí)行,打開cmd壹瘟,切換到il文件所在目錄下鲫剿,執(zhí)行如下命令:c:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe 123.il /output=123.exe /res:123.res /exe
其中c:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe為ilasm.exe的路徑鳄逾;123.il為我們修改后的il文件稻轨;/output=123.exe指我們要輸出的文件名稱;/res:123.res表示要將對應的資源文件也編譯到程序中雕凹;/exe為輸出的文件格式為exe殴俱,如果原始文件dll的,則需要使用/dll
這一步俺也走了彎路枚抵,大家不要走呀线欲,我第一次運行命令的時候,沒有帶/res參數(shù)汽摹,導致編譯出來的exe文件沒有應用程序圖標.
編譯成功后李丰,目錄下會生成123.exe文件
7、測試
對于編譯的123.exe逼泣,打開運行觀察是否是期望的結果趴泌。如果你幸運修改的文字較少不影響控件美觀性舟舒,那么本次任務就圓滿結束了。但我很不幸運嗜憔,增加的文字較多秃励,導致在lable中文字顯示不全。所以俺還需要附帶贈送如下步驟吉捶。
8夺鲜、調整控件位置及大小
在reflector中找到對應控件,找到其location呐舔、size設置的大小币励,還發(fā)現(xiàn)該控件的autosize為true,這是不行的珊拼,需要修改為false榄审,我們才能調整他的大小。
在UE中查找對應位置杆麸,可按照控件方法名定位搁进,數(shù)字可能涉及16進制轉換,在修改時要注意昔头。
IL_025a: ldc.i4.1 //需要修改為ldc.i4.0饼问,表示false
IL_025b: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_AutoSize(bool) //設置autosize
修改控件size大小
IL_02be: ldc.i4 0xdb //長度 按照需要修改吧
IL_02c0: ldc.i4.s 30 //高度 按照需要修改吧
IL_02c2: newobj instance void [System.Drawing]System.Drawing.Size::.ctor(int32,
int32)
修改完成后,重復6揭斧、7步驟莱革,直到控件位置調整正常。
9讹开、完工
將程序發(fā)給客戶驗證盅视,OK!
此次任務完工旦万。
學習過程中遇到什么問題或者想獲取學習資源的話闹击,歡迎加入技術愛好者交流群,我們一起學技術成艘!