|
.net程序的不同 .net程序和以往的Windows應用程序有一個顯著不同的地方:它的可執行文件的組織方式,不像以往的應用程序。.net程序是由MSIL語言進行組織,運行時需要調用即時編譯器(JIT)編譯成本地彙編指令再來執行,好比以前的VB程序一樣,是一個解釋執行的過程。 與指令相對應的是數據,一部分靜態數據或者說是資源,對它們來說.net程序和傳統程序也大大不同。本文主要對.net應用程序資源的組成以及對它的操作進行簡單分析。
托管資源說明 應用程序資源主要包括字符串、圖像、聲音、視頻等,目前最常用的是前麵兩種,本文主要是以在應用bmp文件過程中的經驗做一下簡單說明。在過去,對應於MFC,資源以.rc文件方式組織,程序在使用資源時使用它的資源ID號做為索引,用起來很不方便,而且如果想把資源從應用程序做成一個單獨的資源dll文件,無論是製作還是使用,都是一件非常麻煩的事。 .net程(cheng)序(xu)在(zai)這(zhe)些(xie)方(fang)麵(mian)進(jin)行(xing)了(le)改(gai)進(jin),首(shou)先(xian)在(zai)設(she)計(ji)階(jie)段(duan),它(ta)把(ba)各(ge)種(zhong)資(zi)源(yuan)統(tong)一(yi)保(bao)存(cun)在(zai)資(zi)源(yuan)文(wen)件(jian)裏(li),稱(cheng)作(zuo)托(tuo)管(guan)資(zi)源(yuan)。這(zhe)裏(li)的(de)資(zi)源(yuan)文(wen)件(jian)包(bao)括(kuo)兩(liang)種(zhong),一(yi)種(zhong)是(shi)XML文件,一種是.resources文件。我們使用.net編程序,尤其是用VC.net編程,首要建立一個form窗體,在上麵加一些菜單和按鈕,然後在上麵添加一些圖標,這時對應窗體名還另外生成了一個.resx文件,這就是XML型資源文件。 XML資源文件是由XML標簽文本組成,用托管資源編輯器把這個窗體打開,就可以看到我們添加的圖標和文本。另一種資源文件.resources是以二進製方式存儲資源,它的體積要比XML資源文件小得多,這個文件在設計階段並不存在,隻有VS在編譯.net程序時,才會把XML資源文件轉化為.resources文件,同時VS還會把XML資源文件裏的資源打包進應用程序和dll文件中。 MS為什麼要這麼做,是否有必要做成兩種資源文件形式,還有MS為實現資源打包,還在VS中添加了像托管資源編譯器之類的小工具,這麼不怕麻煩又是為什麼?這所有的問題都指向一個最有深度的解釋:服從.net戰略需要。
托管資源的使用 為方便使用這些資源,需要使用VS中包含的System::Resources程序集,其中操作.resx資源文件的類有ResXResourceSet()、ResXResourceReader()、ResXResourceWriter()。操作.resources文件的類有ResourceSet()、ResourceReader()、ResourceWriter()。這些類大體作用是為前兩個讀資源所用,後一個為寫資源用。 這是直接操作資源文件,當資源被打包進exe或dll(在.net術語中稱為程序集)中之後,我們用ResourceManager類,這個類隻能讀資源。這裏要說明一下如何引用這些資源,用最簡單直接的方式是用名稱引用。舉個例子,如果有一個程序集a.dll,裏麵打包一個r.resx文件,r.resx裏有一個 img.bmp文件,使用這個程序集裏的img.bmp怎麼辦?用幾句話便可以輕鬆解決: System::Resources::ResourceManager ^res = nullptr; Assembly ^Asm1 = Assembly::LoadFile("X:\\a.dll"); res = gcnew System::Resources::ResourceManager("a.r",Asm1); Image ^m=dynamic_cast(res->GetObject("img"));
另類使用方法 除了一些具體的細節可以查看msdn之外,再補充一些非常規的用法。 把所有的資源都放進.resx文件再打包進程序集固然是比較合乎邏輯的做法,如果要直接把資源(這裏特別指的是bmp文件)放進程序集,而不經過打包這一步,是否可行?答案是沒有問題。事實上MS就做了這樣的事,在控件開發過程中,如果要給控件弄一個圖標,可以讓這個圖標顯示在VS的工具箱中,那就必須要給這個圖標(比如一個bmp文件)起一個和控件一樣的名字:(程序集名).(控件名).bmp,然後把這個圖標設置為鏈接器的嵌入托管資源文件。具體設置的方法是,在解決方案資源管理器中,在項目名稱上點右鍵->屬性,在彈出的對話框左麵一欄選擇鏈接器->輸shu入ru,然ran後hou在zai嵌qian入ru托tuo管guan資zi源yuan文wen件jian一yi欄lan中zhong填tian寫xie要yao嵌qian入ru的de資zi源yuan,如ru果guo有you多duo個ge資zi源yuan要yao嵌qian入ru,中zhong間jian用yong逗dou號hao分fen隔ge開kai。設she置zhi好hao之zhi後hou,編bian譯yi,然ran後hou剩sheng下xia的de問wen題ti就jiu是shi引yin用yong。這zhe裏li,引yin用yong也ye不bu是shi用yong常chang規gui的de方fang法fa,而er是shi使shi用yongSystem::IO程序集中的Stream類,以及Assembly類的GetManifestResourceStream方法。具體的引用方法如下: Assembly ^assembly = Assembly::GetExecutingAssembly(); System::IO::Stream ^strm =assembly->GetManifestResourceStream("img.bmp"); Image ^m=System::Drawing::Image::FromStream(strm); 這裏僅僅是對bmp文件的直接嵌入做了說明,如果讀者感興趣的話,也可以試試別的資源。 keyikanchu,zheyangdefangfagengzhijie,danbingmeiyoushujukeyizhengmingzhezhongfangfadesuduhechangguifangfaxiangbiyouduodachaju,dancongkaifadejiaodulaikan,wulunshiqianruhaishiyinyong,zhezhongfangfadoushibijiaojianjie。dangrancongguanlidejiaodushangzhezhongzuofabukequ,xiaolvheguifanhuajingchangshiyiduibuketiaohedemaodun。
後記:開發工具的選擇 下麵介紹一下在開發.net程序過程中經常使用到的兩個工具,以及如何使用它們: 第一個工具是VS自帶的MSIL反彙編工具,可以將程序集以樹形列表的方式顯示出來,也可以將程序集反彙編成IL指令文件。本文主要是用它查看托管資源的名稱,以便在其它地方引用。從文件->打開開始,選擇一個帶的托管資源的dll文件,點打開後,雙擊manifest節點,彈出一個新窗口,上麵就是關於各個引用程序集的說明,在其中查找.mresource,就可以找到托管資源文件名。 第二個工具是大名鼎鼎的reflector,由一名MS的員工編寫,是反編譯和破解.net程(cheng)序(xu)必(bi)不(bu)可(ke)少(shao)的(de)工(gong)具(ju),在(zai)本(ben)文(wen)中(zhong)主(zhu)要(yao)是(shi)用(yong)它(ta)看(kan)看(kan)是(shi)否(fou)已(yi)正(zheng)確(que)地(di)把(ba)資(zi)源(yuan)文(wen)件(jian)直(zhi)接(jie)嵌(qian)入(ru)到(dao)程(cheng)序(xu)集(ji)中(zhong)。這(zhe)個(ge)工(gong)具(ju)的(de)使(shi)用(yong)更(geng)簡(jian)單(dan),打(da)開(kai)程(cheng)序(xu)集(ji)文(wen)件(jian)後(hou),直(zhi)接(jie)點(dian)裏(li)麵(mian)的(de)Resources節點即可,如果已經嵌入資源了的話,這個目錄下麵直接就有這個資源。
|