.NET system learning ---- Globalization & Resources
?
L ????????? Preface
L ????????? Understand the resource file
l ????????? Creating a resource file
l ???????? Use the resource file in the program
l ????????? Naming and deployment of the resource file
L ?????????
?
Preface:
Before learning how to use .NET resource files and how to develop World-Ready programs, let's take a look at why you want to use resource files and use it.
Suppose you want to set the FORM TITLE and LOGO based on the current CULUTRE:
?????? private void1_load (Object sender, system.eventargs e) ?? {
????????????? CultureInfo Ci = New CultureInfo (thread.currentthread.currentuicultuicultuicultuicultuicultuicultuicultuicultuicultuicultuiculture.tostring ());
????????????? switch (ci.tostring (). TOLOWER ()) {
???????????????????? case "zh-cn" :? // Chinese version
???????????????????????????? THIS.TEXT = formtitle_zh_cn
????????????????????????????imglogo.image = new bitmap (Application.Startuppath "/LOGO_EN_CN.JPG");
???????????????????????????
???????????????????? case "en-us" :? // English version
?????????????????????????????????????? THIS.TEXT = formtitle_en_us;
???????????????????????????imglogo.image = new bitmap (Application.Startuppath "/LOGO_EN_US.JPG");
???????????????????????????
???????????????????? default: ?? // default version
????????????????????????????????????? THIS.TEXT = formtitle_neutral
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? iglogo.image = new bitmap (Application.Startuppath "/LOGO_NEUTRAL.JPG");
???????????????????????????
?????????????}
}
This code has two questions:
First, the logo file is exposed to the user, and it is stored in the format of ordinary files, which causing other programs or users to modify these files; users who save hard disk space may also choose to delete it, these may result Application error. Make sure the picture or any other file and the unique security mode together is embedded as a resource file in the program set and load.
Second, this is a World-Ready program. If you need to join a new Culture, you may have to change your source code, join new Case, then recompilation to adapt to new Culture needs, this is a world- The READY program is unrealistic. Developing a World-Ready program is important to ensure the logical interface of the program and the isolation of the resource interface. Add a new Culture resource at any time, we should not recoilate the source. Instead, we only need to prepare the new resource files, then publish it to the user and deploy it in the appropriate directory. Applications should be able to find appropriate resources based on different Culture. The purpose of this article is to help readers understand what is Resources and how to use resources to eliminate the two issues mentioned above.
The full text is divided into four parts:
The first part is some and resource-related concepts.
The second part is an example program (RESOURCEGENERATOR) to explain how to create a resource file.
The third part is another example program (WorldApp) to explain how to use the resource file in the program.
The fourth part is named and deployed with resource files. Introduce the naming method of the .NET and how to configure the resource file in the World-Ready program.
?
First part concept
First understand some concepts:
1. ??????? What is a resource file?
As the name suggests, the resource document is of course all resources. However, what is the resource? The so-called resource here is any data available in the program, such as a string, a picture, or any binary format. A resource file can have multiple language culture versions, for example, a culture.resources file can have English version, Simplified Chinese version of Japanese version. ResourceManager can automatically confirm which version of the call is confirmed according to the Culture and resource file names. Only different resource versions need to join language culture information in the file name (.resource file has a strict naming specification, refer to Section IV: Naming and deployment of resource files).
2. ????????
System.Resources namespace support three types of resources:
.txt file, only string resources. Because it is not possible to be embedded in Assembly, it is easy to expose, and it is modified by other programs or users. The biggest disadvantage is that only string resources are supported, not recommended.
.resx file, consisting of XML, any resource can be added, including binary format. It is also not possible to be embedded in Assembly. There is a dedicated read and write class in the System.Resources namespace. This file created in VS.NET is also converting it to the .resources file and then embed it in Assembly based on the settings.
.resources file, PE format, you can join any resource. The only file that can be embedded in Assembly, and has a dedicated read and write class in the System.Resources namespace (ResourceManager).
3. ??????? Several methods of calling resource files
ResourceManager can return different local resources according to different UICULTURE settings. Different Culture's resource files have a strict naming rule, only by naming according to this rule, CRL can find this local resource according to Culture. PS: Because this is very important, just J. Reference Part IV: Naming and Deployment of Resource Files)
.txt file:
You can't call them directly, you can first convert it into .resources files.
.resx file:
You can use the ResxResourceReader to read, but this method is not intuitive and is not safe, and it is not recommended to call directly .resx file. The correct way is to convert it into a .resources file and then read with ResourceManager. Note that if it is added to the .resx file added in the VS.NET, then they are automatically set to Embedded Resource, and then be converted to Assembly after being converted to .resources files. .resources file:
Divided into two cases:
· ???????? is embedded or compiled into a Satellite assembly:
Use resourceManager's various constructors to get resources in Assembly.
· ???????? Separate files, are not compiled or embedded in Assembly:
You can use the ResourceManager.createFileBaseDResourceManager to get the resource set (resourceset), which is all resources.
Special case:
There is also a special case, that is, when you embed a resource, that is, you don't pass a resource (.resources) to embed a resource (Object) directly in Assembly. This can be embedded in Assembly through the parameter / embed of Al.EXE (Assembly Linker). In this case, ResourceManager is useless because it can only get the .resources resource file (or not in assembly).
Calling such a resource that is directly embedded in Assembly, we need to use the reflection's features to complete. Some related functions in the System.Reflection.assembly class can help us get these resources. You can get the name of all resources through Assembly.getManifestResourceNames, then we can get the corresponding resource through Assembly.getManifestResourceStream (
?
Part 2 Creating a resource file
There are two ways to create a resource file, one is to create the RESGEN tool that comes with .NET SDK, and the other is to write Code to create. Introduce:
1. ??????? Resgen:
This tool comes with .Net itself, it can convert .txt, .resx, convert to .resources files. The.resources file is an XML format file stored in a key-value method, each key corresponds to a value.
,This one
Can be any binary format. If it is a format (key = value) corresponding to the .txt file, ResGen automatically generates the key-value corresponding to the XML file. But ResGen has a limitations that cannot be directly embedded in other format files. For example, you can't put it .bmp in key - worthy of the way, because you can't easily apply .BMP in a format corresponding to (key = value) Store in the .txt file. So resge is mainly for TXT files.
An example: Company1.txt file content is: title = company11
Address = Company1 Address
Phone = 12345678
-------------------------------------------------- ----------------
ResGen Company.txt
If
Then you can use the ResourceManager.
It can also be further further, turn the resources file to an Assembly by Al.EXE (there are many benefits to use Assembly (such as the version information and Culture information, etc.).
Al /out:Company1.dll /embed: company1.resources
You can access the .resources files contained in Assembly by setting the different constructors of ResourcesManager (hereinafter, the example below will be said).
2. ??????? Use IResourCswrite by programming to generate a resource file
One of the biggest disadvantages of the above method is that it is not easy to embed other format resources, because the resources of other formats become key - value correspond to the TXT file is not a very easy thing. So we introduce another method, by programming, using the IResourceSwrite class provided by .NET to embed any resource into the resources file.
?
ResourceGenerator is implemented in this way.
Program main interface:
?
The main method used is:
Private void Ongenerateresource (Object Sender, System.EventArgs E)
{
IResourceWriter RW = New ResourceWriter ("C: / Test.Resources");
?????? switch (style)
?????? {
?????? ?????? case "system.sw":
????????????? rw.addResource (SKEY, SVALUE);
????????????? Break;
????????????? Case "system.drawing.bitmap":
????????????? Bitmap bmp = new bitmap (svalue);
????????????? rw.addResource (SKEY, BMP);
????????????? Break;
????????????? Case "System.drawing.Image":
?????? ?????? Image img = new bitmap (svalue);
????????????? rw.addResource (SKEY, IMG);
????????????? Break;
}
}
Depending on the type of resources, if not the string type, we divide it into the corresponding stream, then join the resoruces (String type can be added directly). The generated is .NET can be used directly .resources file. But the resource CLR thus generated does not automatically recognize according to different Culture. To automatically identify and load the correct resource file, you must first convert .resources to Assembly, and naming according to strict naming methods (refer to Part IV: Naming and deployment of resource files) and deploy it to the correct directory, The CLR can then load the correct resource according to different Culture. ?
The third part uses the resource file in the program
Worldapp.cs is a world-ready program. Its logical interface and resource interface are separated. You can implement the logical interface only Bulid once. Run according to the current Culture call according to the corresponding Satellite assembly (Satellite Equipment Set) to achieve local . Adding a new Culture resource does not need to re-build source, just deploy the corresponding resource assembly to the appropriate directory.
Hereinafter, the implementation of WorldApp:
Program main interface:
The program will load the corresponding resource file according to the current Currentuiculutre when starting.
The code to read the resource file is:
?????? private void setculture (CultureInfo Ci)
?????? {
????????????? // Change Current UI Culture
????????????? thread.currentthread.currentuicultuicultuicultuiculture = Ci;
????????????? // load culture resources.
????????????? String assemblyPath = Application.startuppath "//culture.dll";
????????????? Assembly asm = assmbly.loadfrom (assemblypath);
// resorucemanager constructor will load different resources acording to the the
// Currentuicultuiculture. Which means, IF Currentuiculutre IS "en-us", RM Will Load
// "Culture.en-US.Resources" Automaticly.
// when loading, give the resource name.
?????????????? resourcemanager rm = new resourcemanager ("culture", ASM); ?????????????
????????????? // set title, Culture Info and logo.
????????????? this.lbltitle.text = rm.getstring ("Title");
????????????? this.lblculture.text = rm.getstring ("culture");
????????????? this.lbllogo.text = rm.getstring ("Logotitle");
????????????? this.imglogo.image = (bitmap) RM.GetObject ("logo");}
If the current UICULTURE changes, the corresponding Culture resource can be loaded by explicitly calling SetCulture (CultureInfo Ci).
Now if we have a new Culture resource version, we only need to deploy it in the corresponding Culture directory, WorldApp.exe can be loaded automatically, and the WorldApp.exe program does not have to do any changes (no need to compile).
You can generate resources corresponding to Different Culture by the gadgets of the gadgets, and then deploy the generated assembly asMbly. WorldApp has a new Culture version. what!!
?
The fourth part of the resource file naming and deployment
This section describes how the resource file deployment method and how the CLR recognizes and loads different Culture resources.
· ????????? Named mode
Suppose our application named WorldApp.exe, the default resource file is Culture.Resources, based on this resource file as CuluTre.dll (this is the default version of the resource file). Then we have an En-US Culture version of the resource file, then the resource file name of EN-US must be Culture.en-US.Resources, and the EN-US version of the EN-US version generated according to this resource file must be named Culture. Resources.dll and must join Culture information (generate a .resources generated an assembly: resgender /out:cluture.resources.dll / c: en-us /embedcluture.en-us.resources), the generated assembly must be placed in the program In the eN-us directory under the directory, this CLR can be automatically found. Similarly, if we have a ZH-CN version of the resource file, the name of the resource file must be culture.zh-cn.resources, the generated assembly must be Culture.Resources.dll and placed in the zh-cn directory.
Important: Because the generated .resources file itself does not contain the Culture information, its Culture information is reflected on its file name, so .resources' namings must be added to the CLUTURE message (if not, the generated is the default version). When generating assembly from .resources, because asmbly can specify Culture information (via / c:
To specify, if you need to join Culture information in the name of Assembly, the name of Assembly must be: the default version name <. Resources> .dll, is: culture. [Resources] .dll.
· ????????
The correct deployment method (directory structure) should be:
Worldapp.exe ???????????????????? (main program)
Culture.dll ???? ??????????????????? (including the Culture.Resources resource file)
?????????????
??????
????????????? (EN-US resource directory)
???????????? Culture.Resources.dll ?? (including the culture.en-us.resources resource file)
??????? ??????
????????????? Culture.Resources.dll ?? (including the culture.zh-cn.resources resource file)
?????? ??????
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??????
(NET-CULTURE resource catalog)
????????????? Culture.Resources.dll ?? (including cluture.new-culture.resources)
?????? ?????? ?????? <...> ????????????????????????????????????????????????????????????????????????????
With the above deployment, app.exe is running at runtime, the current thread's currentuiculuture to the corresponding directory to find resource files, such as the current currentuicultuiculture = "en-us", the culture.Resources under the EN-US directory Culture.en-US.Resources in .dll assembly will be loaded. If the CLR traverses the entire directory has not found the corresponding resource file, the default resource file version is loaded (called Hub and Spoke Model mode in MSDN) See: ms-help: //ms.msdnqtr.2004apr.1033/cpguide /html/cpconpackagingdedeningResources.htm).
· ???????? CLR how to load resource files
Important: CLR is matched by file when matching the resource file, it is a key to a key in the field. for example:
The default version of the Culture resource file contains four Key: Title, Culture, Logotitle, Logo.
Chinese version of the Culture resource file contains only three key: Title, Culture, Logo. (No logotitle)
If the current culture is "en-cn", the ZH-CN version of Title, Culture, Logo will be loaded, but because the ZH-CN version does not have logotitle, the CLR will automatically load and the most matching of the zh-CN culture. Version logotitle. If you don't, you will finalize the default version of the resource file.
There is a great advantage: It is not that all resources must have a corresponding Culture version, we can put a common resource in the default version, just isolate the resource-related resources associated with specific Culture.
Important: About Culture:
Culture information is composed of primary mark (culture) and secondary tag (geographically). for example:
EN-US ???? (English - US)
EN-GB ???? (English - UK)
EN-au ???? (English) - Australia)
The main mark is EN, indicating that Culture is English culture, and the secondary mark (geographic) distinguishes out which region is in English.
What is the use of this?
Because the CLR is looking for a rollback method, it is said that he will first find the most batch of resource files. If not, you will search the cultural hierarchy to find the closest to request. Matching resource files and generating an exception as the last means. For example, the CLR is not found when looking for EN-US resources, the CLR will not immediately use the default version, but will first search the cultural hierarchy to find resources closest to EN-US, may be EN-GB or Others), if you find it, use this resource when you run, if you can't find it, you will continue to search for the next layer, and finally match the default version (if the default version is not yet, you will throw an exception). Reference:
L ????????? Applied Microsoft .NET Framework Programming ---- Jeffrey Richter
l ????????? msnd library?