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

其实你也可以汉化,跟着我的步骤来,你也可以进行汉化,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工具。这个工具的代码如下:

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 = ;
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 ==)
{
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[];
string readOrWrite = args[];
string outputFile = fileName;
if (args.Length == )
{
outputFile = args[];
} 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(, line.IndexOf(',')));
string keyvValuePair = line.Substring(line.IndexOf(',') + );
string key=keyvValuePair.Substring(,keyvValuePair.IndexOf(','));
string value=keyvValuePair.Substring(keyvValuePair.IndexOf(',')+);
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文件重新编译,汉化完成!!

不需要了解任何底层知识,就可以汉化!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. Java集合源码学习(五)几种常用集合类的比较

    这篇笔记对几个常用的集合实现,从效率,线程安全和应用场景进行综合比较. >>ArrayList.LinkedList与Vector的对比 (1)相同和不同都实现了List接口,使用类似.V ...

  2. **PHP中替换换行符

    PHP中替换换行符 php 不同系统的换行不同系统之间换行的实现是不一样的linux 与unix中用 \nMAC 用 \rwindow 为了体现与linux不同 则是 \r\n所以在不同平台上 实现方 ...

  3. java中常用的工具类(一)

    我们java程序员在开发项目的是常常会用到一些工具类.今天我汇总了一下java中常用的工具方法.大家可以在项目中使用.可以收藏!加入IT江湖官方群:383126909 我们一起成长 一.String工 ...

  4. hdu 4389 数位dp

    求区间内满足x%fx==0的数的个数,fx为该数各个位数上的数字之和Sample Input21 1011 20 Sample OutputCase 1: 10Case 2: 3 大小不是你想开,想开 ...

  5. 字符串截取函数--C语言(转)

    #include<stdio.h> #include<stdlib.h> char* substring(char* ch,int pos,int length) { char ...

  6. HTML Entity Sets - All

    http://www.htmlentities.com/html/entities/ The view below displays the characters used in the offici ...

  7. HDU 5807 Keep In Touch DP

    Keep In Touch Problem Description   There are n cities numbered with successive integers from 1 to n ...

  8. jsp include指令

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...

  9. JavaScript设计模式——工厂模式

    工厂模式:是一种实现“工厂”概念的面上对象设计模式.实质是定义一个创建对象的接口,但是让实现这个接口的类来决定实例化哪个类.工厂方法让类的实例化推迟到子类中进行.创建一个对象常常需要复杂的过程,所以不 ...

  10. Angular JS 学习之过滤器

    1.过滤器可以使用一个管道字符(|)添加到表达式和指令中: 2.AngularJS过滤器可用于转换数据: **currency:格式化数字为货币格式: **filter:从数组项中选择一个子集: ** ...