zoukankan      html  css  js  c++  java
  • 不需要了解任何底层知识,就可以汉化!Let`s go!!!

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

    其实你也可以汉化,跟着我的步骤来,你也可以进行汉化,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 = 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();
            }
        
        }
    }
    View Code
    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;
            }
        }
    }
    View Code
    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}
    ", 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;
                }
            }
        }
    }
    View Code

    总结:

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

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

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

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

       

  • 相关阅读:
    021.day21 反射 Class类 反射常用操作
    020.day20 线程概述 多线程优缺点 线程的创建 线程常用方法 生命周期 多线程同步
    019.day19 缓冲流 对象流 标准输入输出流
    018.day18 map集合如何实现排序 File类 IO流 字节流 字符流 编码
    017.day17 Map接口 克隆 treeSet集合排重缺陷
    016.day16 HashSet TreeSet 比较器Comparable Comparator
    015.day15
    014.day14
    013.day13
    线程
  • 原文地址:https://www.cnblogs.com/francisYoung/p/3372976.html
Copyright © 2011-2022 走看看