汉化?莫要被这两个字吓到。ide
其实你也能够汉化,跟着个人步骤来,你也能够进行汉化,Let`s go!!!(大鸟飘过)工具
这里汉化的是微软企业类库的配置管理工具EntLibConfig.exe。固然,这里的企业类库是3.0版本的。布局
准备工做:字体
你须要下载Entprise Library,而后找到配置管理工具EntLibConfig.exe。ui
将EntLibConfig.exe及其依赖的文件放置在D:\el目录下this
若是不想下载微软企业类库,也没有关系,这里的方法仍是适用的。spa
首先看一下,要汉化的软件界面:.net
汉化后的界面(部分):命令行
1.第一步 反汇编EntLibConfig.exe文件code
首先,在开始菜单中找到visual studio 命令行工具,而后进入,以下图:
进入visual studio命令行工具后,输入以下命令行:
d:
cd el
ildasm /out:el.il EntLibConfig.exe
第一行命令转到d盘。
第二行命令,进入d:\el目录
第三行调用ildasm反汇编器,并为其传递两个参数:/out:el.il EntLibConfig.exe。此时,ildasm反汇编器会将EntLibConfig.exe文件反汇编成il文件。此时你会在d:\el下发现以下文件:
这个文件中就包含了EntLibConfig中菜单的资源,换句话说,菜单中的英文字母都在这个文件里,所以,咱们的目标就是找到这些英文单词,而后一一替换成中文便可。
第二步:将.resource中的资源提取到一个文本文件中
注:微乳并无公开 .resources文件中的资源格式,所以要想读取或者写入,必须借助于.net中的System.Resources.ResourceReader和System.Resources.ResourceWriter类。我已经将他们进行了封装,而且造成一个名为rsc的命令行工具。你可使用这个工具来将.resources文件中的资源提取到一个文本文件中,并能够将这个文本文件中的资源在写会到.resoruce文件。
在本文的最后,我将贴出这个工具的代码。
首先,使用rsc命令行工具将.resoruce文件中的资源提取到一个文本文件中。输入以下命令(复制):
rsc Microsoft.Practices.EnterpriseLibrary.Configuration.Console.MainForm.resources r r.txt
而后,.resource文件中的资源就被提取到了r.txt文本文件中。
而后,使用记事本打开r.txt文件,在记事本的查找一栏里搜索Action,最终定位到第204行,以下图所示:
这个&Action字符串就是菜单中的那个Action选项,只须要将其替换成中文便可。咱们将其替换为“操做”,以下:
保存文件。
而后再次使用rsc命令行工具,将r.txt保存到Microsoft.Practices.EnterpriseLibrary.Configuration.Console.MainForm.resources中。请输入以下命令:
rsc r.txt w Microsoft.Practices.EnterpriseLibrary.Configuration.Console.MainForm.resources
此时,r.txt中的资源已经被写会到Microsoft.Practices.EnterpriseLibrary.Configuration.Console.MainForm.resources文件中。
第三步,从新编译。
首先,使用ilasm编译器将el.il从新编译成exe文件。请输入以下命令行:
ilasm /out:good.exe el.il
这个命令行调用ilasm编译器,而后为其传递两个参数:/out:good.exe和el.il。ilasm编译器将el.il文件编译成good.exe。
如今,汉化已经完成。
打开good.exe,你会惊奇的发现Action已经被替换成了"操做",以下:
怎么样,是否是颇有成就感!
阅读到此,相信你依然会有不少疑问,譬如我怎么知道资源就在Microsoft.Practices.EnterpriseLibrary.Configuration.Console.MainForm.resources文件中,为何第204行的那个Action就是菜单中的那个Action........这篇文章的目的不是让你完全了解汉化,只是给你一个大概的思路。
上面用到了rsc工具。这个工具的代码以下:
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Resources; namespace Wbs { public class ResourceHelper { private ResourceHelper() {} /// <summary> /// 从指定的资源文件中读取资源 /// </summary> /// <param name="fileName">要读取的资源文件</param> /// <returns>读取到的资源</returns> public static Dictionary<int,Resource> GetResources(string fileName) { ResourceReader reader = new ResourceReader(fileName); System.Collections.IDictionaryEnumerator resourceIterator= reader.GetEnumerator(); Dictionary<int, Resource> resources = new Dictionary<int, Resource>(); int resourceID = 0; while (resourceIterator.MoveNext()) { Resource newResource = new Resource(resourceID,(string)resourceIterator.Key, resourceIterator.Value,resourceIterator.Value.GetType()); resources.Add(resourceID,newResource); resourceID++; } reader.Close(); return resources; } /// <summary> /// 将资源写入到指定的文件中。 /// </summary> /// <param name="fileName">要写入到的资源文件</param> /// <param name="resources">被写入的资源</param> public static void WriteResources(string fileName, IEnumerable<Resource> resources) { if (File.Exists(fileName)) File.Delete(fileName); ResourceWriter writer = new ResourceWriter(fileName); foreach (Resource eachResource in resources) { writer.AddResource(eachResource.Key, eachResource.Value); } writer.Close(); } } }
using System; using System.Collections.Generic; using System.Text; namespace Wbs { public class Resource { int id; string key; object value; Type resourceType; public int ID { get { return this.id; } set { this.id = value; } } public string Key { get { return this.key; } set { this.value = value; } } public object Value { get { return this.value; } set { this.value = value; } } public Type ResourceType { get { return this.resourceType; } set { this.resourceType = value; } } public Resource(int id,string key, object value,Type resourceType) { this.id = id; this.key = key; this.value = value; this.resourceType = resourceType; } } }
using System; using System.Collections.Generic; using System.Text; using System.IO; using Wbs; namespace rsc { class Program { static void Main(string[] args) { if(args.Length ==0) { Console.WriteLine("假设要汉化a.resource资源文件,请参考以下步骤实现(注:只能汉化字符串资源,若是想要汉化字体颜色等资源请....本身弄去。)"); Console.WriteLine("第一步:从a.resource中提取资源到r.txt中,请输入以下命令行:rsc a.resource r r.txt"); Console.WriteLine("第二步:修改r.txt中须要汉化的资源"); Console.WriteLine("第三步:从r.txt中将资源写会到a.resource中,请输入以下命令行:rsc a.resource w r.txt"); return; } string fileName = args[0]; string readOrWrite = args[1]; string outputFile = fileName; if (args.Length == 3) { outputFile = args[2]; } if (readOrWrite == "r") { Dictionary<int,Resource> resources = ResourceHelper.GetResources(fileName); WriteTextTo(outputFile, resources); Console.WriteLine("已将资源以文本形式写入到{0}中",outputFile); return; } if (readOrWrite == "w") { Dictionary<int ,Resource>originalResources= ResourceHelper.GetResources(fileName); IEnumerable<Resource> resourceNew = ReadFrom(outputFile); ChangeResource(originalResources, resourceNew); ResourceHelper.WriteResources(fileName,originalResources.Values); Console.WriteLine("已经资源写入到{0}中",fileName); return; } } /// <summary> /// 将资源以文本形式写入到指定的文件 /// </summary> /// <param name="fileName">要将资源写入到的文件</param> /// <param name="resources">资源</param> private static void WriteTextTo(string fileName,Dictionary<int,Resource> resources) { System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Create); System.IO.StreamWriter sw = new System.IO.StreamWriter(fs,Encoding.UTF8); StringBuilder resourceTextBuilder = new StringBuilder(); foreach (var eachResource in resources) { resourceTextBuilder.AppendFormat("{0},{1},{2}\r\n", eachResource.Key,eachResource.Value.Key, eachResource.Value.Value); } sw.WriteLine(resourceTextBuilder.ToString()); sw.Close(); } /// <summary> /// 从指定的资源文本文件中读取资源。 /// </summary /// <param name="fileNameForText">资源文本文件名</param> /// <returns>返回一个资源集合</returns> private static IEnumerable<Resource> ReadFrom(string fileNameForText) { FileStream fs = new FileStream(fileNameForText, FileMode.Open, FileAccess.Read); StreamReader reader = new StreamReader(fs,Encoding.Default); string line; List<Resource> resources = new List<Resource>(); while ((line = reader.ReadLine()) !="") { int resourceID =Convert.ToInt32( line.Substring(0, line.IndexOf(','))); string keyvValuePair = line.Substring(line.IndexOf(',') + 1); string key=keyvValuePair.Substring(0,keyvValuePair.IndexOf(',')); string value=keyvValuePair.Substring(keyvValuePair.IndexOf(',')+1); Resource newResource = new Resource(resourceID,key,value,null); resources.Add(newResource); } return resources; } /// <summary> /// 将资源修改成指定的资源 /// </summary> /// <param name="originalResource">要修改的资源</param> /// <param name="resourceNew">要将资源修改为的新资源</param> private static void ChangeResource(Dictionary<int, Resource> originalResource, IEnumerable<Resource> resourceNew) { foreach (Resource eachResource in resourceNew) { if(originalResource[eachResource.ID].ResourceType.FullName=="System.String") originalResource[eachResource.ID].Value = eachResource.Value; } } } }
总结:
能够先将要汉化的程序集,经过ildasm反汇编器将其反汇编,此时会生成一堆.il文件和.resource文件。你能够在.resource文件中找到要替换的英文。
因为.resource文件的内部结构时不公开的,可是能够经过System.Resources.ResourceReader和System.Resources.ReousrceWriter来读取和写入.resource文件(经过研究这两个类的源码,也能够知道.resoruce文件的内部布局),固然,你可使用我封装好的rsc工具来读取和写入.resource文件。
使用rsc文件将.resoruce文件中的资源提取到一个文本文件中,而后搜索要汉化的字符差,将其替换成中文,最后在使用rsc将其保存到源文件中。
到此为止,汉化以基本完成。此时使用ilasm汇编器将生成的il文件从新编译,汉化完成!!