【dinghao】在.net程式中使用資源

iDotNetSpace發表於2008-06-05
有兩種使用資源(resources)的方式:直接嵌入到程式集或者載入外部檔案。
    如果使用外部檔案方式,必須隨程式集部署外部檔案(資源),並且保證在執行是可以訪問到資原始檔。如果資原始檔和程式集(.exe)永遠也不能相會,則會導致問題。
    第一種方式部署相對第二種會穩定且出錯的機率更小。
    作外嵌入的資源編譯(直接嵌入)
    步驟:
    1、把資源作為嵌入式資源編譯
         By doing this, you have instructed Visual Studio to embed the file into the physical image of the output assembly .exe file.
    2在執行時訪問資源的方法
【dinghao】在.net程式中使用資源'*** get current Assembly object.
【dinghao】在.net程式中使用資源
Dim asm As Assembly = Assembly.GetExecutingAssembly()
【dinghao】在.net程式中使用資源
'*** load embedded resource into stream
【dinghao】在.net程式中使用資源
Dim ResourceName As String = "LitwareSmartClient.LitwareLogo.png"
【dinghao】在.net程式中使用資源
Dim str As Stream = asm.GetManifestResourceStream(ResourceName)
【dinghao】在.net程式中使用資源    
'*** convert stream into image and load in    '*** picture box
【dinghao】在.net程式中使用資源
    Dim img As Image = Image.FromStream(str)
【dinghao】在.net程式中使用資源    PictureBox1.Image 
= img
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    資源名是大小寫敏感的,即使在vb等不敏感的語言中。除了圖片,還可以方便的嵌入基於文字的檔案,如:xml,js,sql
    使用資原始檔
    這是在.net中使用資源的另一種方式,在某些場景下它會更簡單。另,vs中提供了便捷的使用方式。
    通過非vs方式使用資源
    在.net中,資原始檔被用來在程式集中嵌入資源,使用資原始檔的最重要的益處是:可以使程式集中的語言和本地化元素 從程式碼中分離出來。 要實現分離需要為每種需要支援的語言建立一個資原始檔,資原始檔是包含xml的文字檔案,以resx為副檔名,下面是一個資原始檔的片斷:
【dinghao】在.net程式中使用資源<root>
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源 
<data name="MainFormCaption">
【dinghao】在.net程式中使用資源   
<value>Litware Customer Managervalue>
【dinghao】在.net程式中使用資源 
data>
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源 
<data name="UserWelcome">
【dinghao】在.net程式中使用資源   
<value>Good dayvalue>
【dinghao】在.net程式中使用資源 
data>
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源 
<data name="ErrorMessage1">
【dinghao】在.net程式中使用資源   
<value>Oh no, Something went wrong!value>
【dinghao】在.net程式中使用資源 
data>
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
root>
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
可以用Resgen.exe把資原始檔編譯成二進位制映象(binary image ),編譯命令:
    RESGEN.EXE LitwareStrings.resx LitwareStrings.resources
    被編譯成*.resources.
要想使用資源還要把它編譯成程式集,命令:
    AL.EXE /t:library 
     /out:LitwareStrings.resources.dll 
     /link:LitwareStrings.resources
使用方式:
【dinghao】在.net程式中使用資源Dim asm As Assembly = Assembly.Load("LitwareStrings.resources")
【dinghao】在.net程式中使用資源Dim rm As New System.Resources.ResourceManager("LitwareStrings", asm)
【dinghao】在.net程式中使用資源Dim caption As String = rm.GetString("MainFormCaption")
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    下面把資原始檔編譯成強型別的資源類,   
     RESGEN.EXE LitwareStrings.resx LitwareStrings.resources /str:vb 
      這樣就可以通過屬性訪問資源,編譯後的資原始檔包含LitwareStrings類,此類會用ResourceManager 實現強型別的屬性如:
【dinghao】在.net程式中使用資源Shared ReadOnly Property MainFormCaption() As String
【dinghao】在.net程式中使用資源  
Get
【dinghao】在.net程式中使用資源    
Return ResourceManager.GetString("MainFormCaption", resourceCulture)
【dinghao】在.net程式中使用資源  
End Get
【dinghao】在.net程式中使用資源
End Property
 

    在vs2005中使用資原始檔:
    步驟:
1、新增一個資原始檔
2、vs會編譯.resx到.resources ,然後連線程式集的物理映象(physical image )
vs也會建立一個強型別的資源類,此類在mynamespace下面。(c#不知會在哪?)不要直接訪問資源類,而要通過ResourceManager,訪問程式碼:
【dinghao】在.net程式中使用資源Sub Main_Load(sender As Object, e As EventArgs) 
【dinghao】在.net程式中使用資源  
Handles MyBase.Load
【dinghao】在.net程式中使用資源  
Me.Text = _
【dinghao】在.net程式中使用資源    My.Resources.LitwareStrings.MainFormCaption
【dinghao】在.net程式中使用資源  
Me.lblUserWelcome.Text = _
【dinghao】在.net程式中使用資源    My.Resources.LitwareStrings.UserWelcome
【dinghao】在.net程式中使用資源
End Sub

【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    專案級別的資原始檔
    你可以顯式的在vs中增加一個或多個資原始檔,但是這通常是沒有必要的,因為建立工程時,vs會建立一個專案級別的資原始檔。此檔案可以通過專案屬性對話方塊訪問。
    你可以象下面那樣訪問資原始檔中的文字:
    
【dinghao】在.net程式中使用資源Private Sub LoadResources()
【dinghao】在.net程式中使用資源  
'*** load project-level resources
【dinghao】在.net程式中使用資源
  Me.Text = My.Resources.MainFormCaption
【dinghao】在.net程式中使用資源  
Me.lblWelcomeMessage.Text = My.Resources.UserWelcome
【dinghao】在.net程式中使用資源
End Sub

【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    你可以看到,通過強型別訪問資原始檔中的字串是多麼的簡單!更進一不,你可以同樣的訪問強型別的資原始檔,即使這些資原始檔包含圖片,以xml,sql,js為內容的檔案。
    例如,假定你增加LitwareLogo.png 和resources.xml到專案級別的資原始檔,這些資源會自動的嵌入到專案的輸出程式集。你可以用強型別的方式訪問他們,程式碼:
【dinghao】在.net程式中使用資源Me.picLogo.Image = My.Resources.LitwareLogo
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
Dim xmlDoc As New Xml.XmlDocument
【dinghao】在.net程式中使用資源xmlDoc.LoadXml(My.Resources.Customers)
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    你可以看到強型別的資源類自動的轉換.png檔案為Image物件,並且能被直接載入到PictureBox,強型別的資源類也自動轉換.xml檔案為字串,然後字元可以方便的被載入到XmlDocument物件。
    資源設定和本地化:
    軟體專案被本地化是通用的需求,這樣它就能被說不同語言的人群使用。.net提供了方便的方法來本地化程式和Dll庫。
    首先你要熟悉CultureInfo類,一個CultualInfo物件,跟蹤一個Cultual name,一個Cultual Name
標誌了一種語言。
    英文的cultual name 是“en”,法國是“fr”,也可以包含附加資訊,此資訊指定了區域性(region),如,美國英語的“en-us”,英國英語的“en-gb”.下面的程式碼建立並初始化了一個CultureInfo物件
【dinghao】在.net程式中使用資源Dim culture1 As CultureInfo = New CultureInfo("en-US")
【dinghao】在.net程式中使用資源
Dim culture2 As CultureInfo = New CultureInfo("en-GB")
【dinghao】在.net程式中使用資源
Dim culture3 As CultureInfo = New CultureInfo("fr")
【dinghao】在.net程式中使用資源
Dim culture4 As CultureInfo = New CultureInfo("fr-BE")
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    有兩個CultureInfo物件關聯到當前執行緒,第一個CultureINfo物件列出了當前風俗(Culture)的表示形式,第二個CultureINfo物件表示當前的UI風俗(Culture)。( The first CultureInfo object listed represents the current culture while the second CultureInfo object represents the current UI culture.)
    可以通過下面的程式碼列出兩個CultureINfo物件的兩個Culture names,
【dinghao】在.net程式中使用資源'*** determine current culture and current UI culture
【dinghao】在.net程式中使用資源
Dim t As Thread = Thread.CurrentThread
【dinghao】在.net程式中使用資源
Dim currentCulture As CultureInfo = t.CurrentCulture
【dinghao】在.net程式中使用資源
Dim currentUICulture As CultureInfo = t.CurrentUICulture
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
'*** display cultures in console
【dinghao】在.net程式中使用資源
Console.WriteLine("Current Culture: " & currentCulture.Name)
【dinghao】在.net程式中使用資源Console.WriteLine(
"Current UI Culture: " & currentUICulture.Name)
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    名為CurrentCulture 的第一個CultureInfo物件不能被用來在程式中本地化字串,它隻影響.netFramework格式化日期,數字,貨幣。因此當本地化程式以適應多語言時也不要修改此屬性(static it)。
    如果你必須用程式修改CurrentCulture ,一定要用包含區域的Culture name,如:“en-us”
。如果沒有區域資訊,如,"en",則會丟擲異常,因為執行時不能確定如何格式化。
    名為CurrentUICulture 的第二個CultureINfo物件對本地化來說是很重要的。修改關聯到當前執行緒的CurrentUICulture 將影響.net framework和ResourceManager類如何載入包含內嵌資源的程式集。
    本地化的步驟
    1、拷貝多份資原始檔,一份對應一種要支援的語言。如:做一個專案範圍(project-wide) 的資原始檔:Resources.resx,然後拷貝多份。
    2、重新命名拷貝的檔案,檔名的格式是,在resx前加Culture name。如:為通用的法文字地化字符集(French localized strings )的資原始檔命名為Resources.fr.resx ,為比利時專用的法文字地化字符集命名為Resources.fr-BE.resx 。
    Satellite程式集
    當編譯包含本地化資原始檔的工程(此工程含有多個資原始檔,如上面的例子)時,vs不會把所有的資原始檔編譯到一個輸出程式集,而是每個資原始檔被編譯到單獨的程式集。這種程式集盡包含資源沒有程式碼。這種僅含有資源的本地化程式集被稱為“satellite assembly”。
    每個Satellite程式集和稱作“neutral assembly”的主程式集相關聯。中立程式集在需要時載入Satellite程式集以獲取本地化資源。
    當Satellite程式集和Neutral程式集部署在AppBase目錄下時,部署必須符合程式集載入器的規則。每個Satellite程式集必須部署在已它的本地化Cultual name命名的資料夾下面。如:
AppBase下包含LitwareSmartClient.exe 中立程式集,也必須包含fr-BE 子目錄,此子目錄包含名為LitwareSmartClient.resources.dll的為比利時法語本地化的Satellite程式集。只要符合規則.net
程式集載入器和輔助的ResourceManager 類就可以在需要的時候載入正確的資源。
    幸運的是,Vs知道怎麼正確的命名Satellite程式集並正確的部署他們。
    載入本地化的資源
    當你建立編輯了本地化資原始檔並且編譯了工程,就是要關注怎麼讓程式載入使用者需要的本地化字元的時候。一種方法是,獲取當前執行緒的引用,並且把CurrentUICulture 屬性設定為新建立的CultureInfo物件。在winform的vb程式碼如下:
【dinghao】在.net程式中使用資源My.Application.ChangeUICulture("fr-BE")
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    另一種是使用註冊鍵。
    注意,net 程式集載入器首先精確匹配(language and region)Satellite程式集,如果不成功則查詢可用的只匹配語言的程式集。如果還不匹配就使用Neutual程式集內嵌的資源。
    當編譯Neutal程式集時,可以通過一個特殊的屬性為它指定預設的Cultual 資源。如,在assemblyInfo.vb中加入:
【dinghao】在.net程式中使用資源<Assembly: System.Resources.NeutralResourcesLanguage("en")>
【dinghao】在.net程式中使用資源
【dinghao】在.net程式中使用資源
    當如此指定時,NeutralResourcesLanguage 特性將通知程式集載入器:當使用者請求本地化為英文的程式時,將使用預設cultual 資源。
    本地化窗體和控制元件設定
    你已經知道了怎麼在專案範圍(project-wide)的基礎上本地化資源,這種技術涉及到拷貝和修改本地化資原始檔。vs對本地化窗體和控制元件提供了額外的幫助,但通過這種方式對以後增加語言支援會很複雜,一種簡單的方式是,建立資原始檔,這種方式,你不用編譯Netual程式集,這是.netframework在本地化程式和Dll庫方面最有價值的特色。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-332339/,如需轉載,請註明出處,否則將追究法律責任。

相關文章