汉化?莫要被这两个字吓到。

其实你也可以汉化,跟着我的步骤来,你也可以进行汉化,Let`s go!!!(大鸟飘过)

这里汉化的是微软企业类库的配置管理工具EntLibConfig.exe。当然,这里的企业类库是3.0版本的。

准备工作:

你需要下载Entprise Library,然后找到配置管理工具EntLibConfig.exe。

将EntLibConfig.exe及其依赖的文件放置在D:\el目录下

如果不想下载微软企业类库,也没有关系,这里的方法还是适用的。

首先看一下,要汉化的软件界面:

汉化后的界面(部分):

1.第一步 反汇编EntLibConfig.exe文件

首先,在开始菜单中找到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工具。这个工具的代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. using System.Resources;
  6.  
  7. namespace Wbs
  8. {
  9. public class ResourceHelper
  10. {
  11. private ResourceHelper()
  12. {}
  13.  
  14. /// <summary>
  15. /// 从指定的资源文件中读取资源
  16. /// </summary>
  17. /// <param name="fileName">要读取的资源文件</param>
  18. /// <returns>读取到的资源</returns>
  19. public static Dictionary<int,Resource> GetResources(string fileName)
  20. {
  21. ResourceReader reader = new ResourceReader(fileName);
  22. System.Collections.IDictionaryEnumerator resourceIterator= reader.GetEnumerator();
  23. Dictionary<int, Resource> resources = new Dictionary<int, Resource>();
  24. int resourceID = ;
  25. while (resourceIterator.MoveNext())
  26. {
  27. Resource newResource = new Resource(resourceID,(string)resourceIterator.Key, resourceIterator.Value,resourceIterator.Value.GetType());
  28. resources.Add(resourceID,newResource);
  29. resourceID++;
  30. }
  31. reader.Close();
  32. return resources;
  33. }
  34.  
  35. /// <summary>
  36. /// 将资源写入到指定的文件中。
  37. /// </summary>
  38. /// <param name="fileName">要写入到的资源文件</param>
  39. /// <param name="resources">被写入的资源</param>
  40. public static void WriteResources(string fileName, IEnumerable<Resource> resources)
  41. {
  42. if (File.Exists(fileName))
  43. File.Delete(fileName);
  44. ResourceWriter writer = new ResourceWriter(fileName);
  45. foreach (Resource eachResource in resources)
  46. {
  47. writer.AddResource(eachResource.Key, eachResource.Value);
  48. }
  49. writer.Close();
  50. }
  51.  
  52. }
  53. }
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4.  
  5. namespace Wbs
  6. {
  7. public class Resource
  8. {
  9. int id;
  10. string key;
  11. object value;
  12. Type resourceType;
  13.  
  14. public int ID
  15. {
  16. get { return this.id; }
  17. set { this.id = value; }
  18. }
  19.  
  20. public string Key
  21. {
  22. get { return this.key; }
  23. set { this.value = value; }
  24. }
  25.  
  26. public object Value
  27. {
  28. get { return this.value; }
  29. set { this.value = value; }
  30. }
  31.  
  32. public Type ResourceType
  33. {
  34. get { return this.resourceType; }
  35. set { this.resourceType = value; }
  36. }
  37.  
  38. public Resource(int id,string key, object value,Type resourceType)
  39. {
  40. this.id = id;
  41. this.key = key;
  42. this.value = value;
  43. this.resourceType = resourceType;
  44. }
  45. }
  46. }
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. using Wbs;
  6.  
  7. namespace rsc
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. if(args.Length ==)
  14. {
  15. Console.WriteLine("假设要汉化a.resource资源文件,请参考如下步骤实现(注:只能汉化字符串资源,如果想要汉化字体颜色等资源请....自己弄去。)");
  16. Console.WriteLine("第一步:从a.resource中提取资源到r.txt中,请输入如下命令行:rsc a.resource r r.txt");
  17. Console.WriteLine("第二步:修改r.txt中需要汉化的资源");
  18. Console.WriteLine("第三步:从r.txt中将资源写会到a.resource中,请输入如下命令行:rsc a.resource w r.txt");
  19. return;
  20. }
  21. string fileName = args[];
  22. string readOrWrite = args[];
  23. string outputFile = fileName;
  24. if (args.Length == )
  25. {
  26. outputFile = args[];
  27. }
  28.  
  29. if (readOrWrite == "r")
  30. {
  31. Dictionary<int,Resource> resources = ResourceHelper.GetResources(fileName);
  32. WriteTextTo(outputFile, resources);
  33. Console.WriteLine("已将资源以文本形式写入到{0}中",outputFile);
  34. return;
  35. }
  36.  
  37. if (readOrWrite == "w")
  38. {
  39. Dictionary<int ,Resource>originalResources= ResourceHelper.GetResources(fileName);
  40. IEnumerable<Resource> resourceNew = ReadFrom(outputFile);
  41. ChangeResource(originalResources, resourceNew);
  42. ResourceHelper.WriteResources(fileName,originalResources.Values);
  43. Console.WriteLine("已经资源写入到{0}中",fileName);
  44. return;
  45. }
  46. }
  47. /// <summary>
  48. /// 将资源以文本形式写入到指定的文件
  49. /// </summary>
  50. /// <param name="fileName">要将资源写入到的文件</param>
  51. /// <param name="resources">资源</param>
  52. private static void WriteTextTo(string fileName,Dictionary<int,Resource> resources)
  53. {
  54.  
  55. System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Create);
  56. System.IO.StreamWriter sw = new System.IO.StreamWriter(fs,Encoding.UTF8);
  57. StringBuilder resourceTextBuilder = new StringBuilder();
  58.  
  59. foreach (var eachResource in resources)
  60. {
  61. resourceTextBuilder.AppendFormat("{0},{1},{2}\r\n", eachResource.Key,eachResource.Value.Key, eachResource.Value.Value);
  62. }
  63. sw.WriteLine(resourceTextBuilder.ToString());
  64. sw.Close();
  65. }
  66.  
  67. /// <summary>
  68. /// 从指定的资源文本文件中读取资源。
  69. /// </summary
  70. /// <param name="fileNameForText">资源文本文件名</param>
  71. /// <returns>返回一个资源集合</returns>
  72. private static IEnumerable<Resource> ReadFrom(string fileNameForText)
  73. {
  74. FileStream fs = new FileStream(fileNameForText, FileMode.Open, FileAccess.Read);
  75. StreamReader reader = new StreamReader(fs,Encoding.Default);
  76. string line;
  77. List<Resource> resources = new List<Resource>();
  78. while ((line = reader.ReadLine()) !="")
  79. {
  80. int resourceID =Convert.ToInt32( line.Substring(, line.IndexOf(',')));
  81. string keyvValuePair = line.Substring(line.IndexOf(',') + );
  82. string key=keyvValuePair.Substring(,keyvValuePair.IndexOf(','));
  83. string value=keyvValuePair.Substring(keyvValuePair.IndexOf(',')+);
  84. Resource newResource = new Resource(resourceID,key,value,null);
  85. resources.Add(newResource);
  86. }
  87.  
  88. return resources;
  89. }
  90.  
  91. /// <summary>
  92. /// 将资源修改为指定的资源
  93. /// </summary>
  94. /// <param name="originalResource">要修改的资源</param>
  95. /// <param name="resourceNew">要将资源修改成的新资源</param>
  96. private static void ChangeResource(Dictionary<int, Resource> originalResource, IEnumerable<Resource> resourceNew)
  97. {
  98. foreach (Resource eachResource in resourceNew)
  99. {
  100. if(originalResource[eachResource.ID].ResourceType.FullName=="System.String")
  101. originalResource[eachResource.ID].Value = eachResource.Value;
  102. }
  103. }
  104. }
  105. }

总结:

可以先将要汉化的程序集,通过ildasm反汇编器将其反汇编,此时会生成一堆.il文件和.resource文件。你可以在.resource文件中找到要替换的英文。

由于.resource文件的内部结构时不公开的,但是可以通过System.Resources.ResourceReader和System.Resources.ReousrceWriter来读取和写入.resource文件(通过研究这两个类的源码,也可以知道.resoruce文件的内部布局),当然,你可以使用我封装好的rsc工具来读取和写入.resource文件。

使用rsc文件将.resoruce文件中的资源提取到一个文本文件中,然后搜索要汉化的字符差,将其替换成中文,最后在使用rsc将其保存到源文件中。

到此为止,汉化以基本完成。此时使用ilasm汇编器将生成的il文件重新编译,汉化完成!!

不需要了解任何底层知识,就可以汉化!Let`s go!!!的更多相关文章

  1. Sublime text 3中文汉化教程

    想弄个中文版的sublime,居然可以不用重新下载汉化包或者重新下载简体中文版了~而是只需要安装个插件即可!   工具/原料   电脑 sublime text3编辑器 方法/步骤    启动并进入s ...

  2. Ubantu中sublime汉化

    1 启动并进入sublime主界面: 2 如图所示,点击菜单栏中“preferences”,弹出选项中找到“package control”: 3 进入下一步,选择“install package”: ...

  3. 如何下载中文语言包让Eclipse汉化?

    Eclipse软件是JAVA开发必备的软件,对于英语不好的人而言面对英文代码还好,但是软件也是英语的那就头疼了,怎么解决?可以去官网下载中文语言包解压到Eclipse安装目录就可以汉化了.   工具/ ...

  4. 记一次重复造轮子(Obsidian 插件设置说明汉化)

    杂谈 #Java脚本 因本人英语不好在使用Obsidian时,一些插件的设置英文多令人头痛.故有写一个的翻译插件介绍和设置脚本的想法.看到有些前人写的一下翻译方法,简直惨目忍睹.竟然要手动.这个应该写 ...

  5. 写给Android App开发人员看的Android底层知识(1)

    这个系列的文章一共8篇,我酝酿了很多年,参考了很多资源,查看了很多源码,直到今天把它写出来,也是战战兢兢,生怕什么地方写错了,贻笑大方. (一)引言 早在我还是Android菜鸟的时候,有很多技术我都 ...

  6. 写给Android App开发人员看的Android底层知识(5)

    (十)Service Service有两套流程,一套是启动流程,另一套是绑定流程.我们做App开发的同学都应该知道. 1)在新进程启动Service 我们先看Service启动过程,假设要启动的Ser ...

  7. JS底层知识理解之执行上下文篇

    JS底层知识理解之执行上下文篇 一.什么是执行上下文(Execution Context) 执行上下文可以理解为当前代码的执行环境,它会形成一个作用域. 二.JavaScript引擎会以什么方式去处理 ...

  8. Java底层知识学习:Bytecode and JMM

    最近在跟着耗子哥的程序员练级指南学习Java底层知识,结合<深入理解Java虚拟机>这本书在看,写笔记,看资料,成长中…… 目前看完了第二章JMM和各内存区OOM的情况 一篇图文并茂介绍字 ...

  9. 极客时间-左耳听风-程序员攻略-Java底层知识

    Java 字节码相关 字节码编程,也就是动态修改或是动态生成 Java 字节码.Java 的字节码相当于汇编,其中的一些细节. Java Zone: Introduction to Java Byte ...

随机推荐

  1. Linq to json

    Json.Net系列教程 4.Linq To JSON 一.Linq to JSON是用来干什么的? Linq to JSON是用来操作JSON对象的.可以用于快速查询,修改和创建JSON对象.当JS ...

  2. LeetCode之Binary Tree Level Order Traversal 层序遍历二叉树

    Binary Tree Level Order Traversal 题目描述: Given a binary tree, return the level order traversal of its ...

  3. asmlinkage

    转自:http://www.cnblogs.com/china_blue/archive/2010/01/15/1648523.html 声明,仅为了便于自己记忆和查询,非原创,摘自:http://b ...

  4. windows操作技巧

    -------------------win7专有------------------- WIN+上下左右可以将当前窗口 最大化.左侧放置.右侧放置.最小化 WIN+Shift+左右是让窗口在多个屏幕 ...

  5. 记录一次冷备恢复遇到的 ORA-00304问题

    希望通过冷备一个数据库,然后在另外一台数据库进行恢复 1.打tar包 tar -czvf Prod.tar.gz *control01.ctlcontrol02.ctlredo01.logredo02 ...

  6. c++ 的 static_cast

    http://www.cnblogs.com/pigerhan/archive/2013/02/26/2933590.html #include "Person.h" #inclu ...

  7. 攻城狮在路上(壹) Hibernate(八)--- 映射Hibernate组成关系

    一.使用组成关系的原则: 在不导致数据冗余的前提下,尽可能减少数据库表的数目及表之间的外键参照关系,因为建立多个表的连接是很耗时的操作. 举例说明:Customer类中的Address属性,可以通过组 ...

  8. MyEclipse 关闭鼠标悬停提示

    preference --> MyEclipse -->Files and Editors--> Common Editor Preference --> Hovers 把里面 ...

  9. SercureCRT无法正常连接Ubuntu14.0.4.1的解决办法

    问题描述 通过VirtualBox重新安装了ubuntu 14.0.4.1 虚拟服务器,在SercureCRT中使用root帐号连接ubuntu14.0.4.1的时候,提示“Password Auth ...

  10. loopback 02

    数据库连接操作,以mongodb为例 安装loopback-connector-mongodb 修改datasources.json //例子 { "db": { "na ...