zoukankan      html  css  js  c++  java
  • 汉化

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

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

    }
    }

    复制代码
    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;
    
    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} ", 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;
    }
    }
    }
    }

    复制代码
    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;
                }
            }
        }
    }
    复制代码

    总结:

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

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

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

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

       

  • 相关阅读:
    将Hive统计分析结果导入到MySQL数据库表中(一)——Sqoop导入方式
    hive基本结构与数据存储
    使用sqoop从Oracle或mysql抽取数据到HDFS遇到的报错及解决
    Sqoop导入关系数据库到Hive
    SVN版本回退
    SVN--分支、合并
    关于SVN版本分支合并的知识
    在spring环境下集成ActiveMQ
    ActiveMQ
    Oracle中sequence的使用方法
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3373470.html
Copyright © 2011-2022 走看看