前段时间在研究某游戏辅助,老外出品,支持七种语言,可这辅助相关的插件却少有中文,因为作者都是老外,并且他们不愿意添加中文。有一些没有加密的插件就被善良的国内用户使用工具软件手工汉化了,但是经过混淆加密的插件就比较困难了,一是需要解密,二是插件数量多更新快,最后弄得只好放弃。有一天,一位用户问我,能不能做一个补丁程序,不去解密也不去修改源程序,只是在窗口显示的时候把文字汉化,他的意思就是hook窗体显示的过程,显然,这是个很不错的想法。

很多年前,曾经流行过一个名叫“南极星”的软件,后来又出了个“金山快译”,这两个都是可以把程序界面进行本地化的外挂,而我要做的却是补丁,也就是内挂,虽然形式不同,但原理上总是相通的吧。抱着这种想法,开始了新的代码之旅,但没过多久我就彻底放弃了,主要原因是只支持window窗口,对WPF无效,因为WPF窗体中的内容不是有效控件,而且在“自动”方面上更是难以为继。

我的关子已经卖得够多了吧,你知道的,最终我还是达到了目的。

.NET的程序只有在在.NET的环境中才会如渔得水般的灵活。对于普通winform和WPF窗体,在窗口构造函数运行之后,我们只需要遍历窗口类的所有私有字段就可以得到全部的控件了,直接修改其对应的文字,这就是汉化的全过程!那么问题来了,一如何拿到窗口的实例引用,二如何在窗口显示以前修改文字,三对于用户自定义的窗体控件如何处理。下面一一解答。

第一个问题,可以从进程的Application中获取当前的WPF窗口或是Winform窗口集合,再用循环查找新窗口的方法通过异步修改其内容。但这不是我想要的,因为这样不效率,会有延迟和状态判断的问题,而我需要的是个每当窗口创建时才会调用的callback方法,hook在我需要的位置上。实际上最好的本地化时机是在窗口对象创建结束,但还没有被显示出来的时候,这时窗体内的控件和内容都创建完毕,在等着我们修改。当然,这个问题最后肯定是有答案的,请往下看。

第二个问题是通过MethodReplace的不正当手段实现的,原理就是在CLR中修改方法MethodDesc中代码地址来实现的,在调用源方法的方法还没有被Jit前用新方法的地址来代替源方法,使源方法在被调用时整个方法体转向到新方法中(具体过程请Google)。因为显示窗口的方法都是由.NET提供现成编译好的本地代码,是无法替换地址的,所以最好的切入点就是窗口的构造函数。通过遍历已经加载的程序集和当前Domain的AssemblyLoad事件,可以轻易的在程序集被装载时拿到控制权,然后遍历程序集中所有的窗口类,然后对它们的构造函数进行方法转向,这样就抢在了创建窗口的方法被Jit之前。想一想,所有窗口中的控件都需要在构造函数中创建,这通常是通过调用一个名为InitializeComponent的方法,但是这个方法名是不靠谱的,因为它会被混淆,所以仍然要在新方法中使用Opcodes.Calli字段以正确的签名来调用构造方法的源地址(具体请参看MSDN)来完成窗体内控件的初始化过程,这样一来问题就解决了,直接遍历修改即可。等等,怎么修改的内容不全面,还有遗漏。好吧,我忘了有些列表的内容是在窗口第一次被显示时被初始化的,这个问题是VS的IDE造成的,弄得大家都喜欢把用户初始化的数据放在窗口的Load事件中。如何应对?很简单,我把汉化的过程也添加到Load事件中,这样就让汉化的过程发生在窗口原始Load事件之后了。在第二个问题完美解决时,第一个问题也被解决了,窗口的构造函数是实例方法,实例方法的第一个参数永远是this,因此,添加事件、反射修改私有字段都得以实现,还可以实现更多本地化以外的事情……

第三个问题相对就简单多了,唯独的只是繁杂。我们知道绝大多数近件的文字都放在名为Text的属性之中,直接修改或是反射修改就可以,但有少数控仍需要特殊处理,例如:ToolTip控件的Caption属性,菜单的层级结构,列表近件中的内容集合,PropertyGrid中的特性名称。再有,就是一些自定义风格的窗口类,它们控件的文字可能会放在名为Text、Title、SubTitle、Caption、Value1、Value2等等属性中,利用反射遍历查询一下就可以了,当然还要为这些类型和字段做缓存的,这会提升效率。

后来,功能虽然实现了,但它并不好用,用户体验很差劲,主要是自动翻译的效果非常不理想,但我实在是无法解决这种复杂的专业问题的,所以,果断放弃自动翻译,转为输出列表,然后再有目的的翻译。

转载于:https://www.cnblogs.com/ccddnet/p/4021153.html

在CLR中自动本地化正在运行的.NET窗口相关推荐

  1. 在Red Hat Linux中自动运行程序

    在Red Hat Linux中自动运行程序 1.开机启动时自动运行程序 Linux加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init.init根据配置文件继续引导过程,启动其它进程.通常 ...

  2. 在Ubuntu中自动运行KMS服务

    在Ubuntu中自动运行KMS服务 安装最新的vlmcsd releases版本 使用wget下载: wget https://github.com/Wind4/vlmcsd/releases/dow ...

  3. 暗备用的运行状态_备用电源自动投入装置运行中遇到的问题

    摘要: 备用电源自动投入装置(以下简称:备自投)对保证供电可靠性起了很大的作用,但 在实际应用中,遇到不少问题. 1 前言 本文将本人在实际工作中遇到的几种备自投有关问题一一列举, 并根据具体情况参考 ...

  4. gettext 国际化_如何使用Gettext在Phoenix应用程序中执行本地化

    gettext 国际化 by Anastasia 由Anastasia 如何使用Gettext在Phoenix应用程序中执行本地化 (How to perform localization in Ph ...

  5. ios swiftui_ios swiftui中的本地化

    ios swiftui 本土化 (Localisation) Localisation is the process of making your app support another langua ...

  6. 如何在Windows 2000的域环境中自动分发软件

    如何在Windows 2000的域环境中自动分发软件 一,对于Windows 9x/ME/NT的客户端计算机,我们可以通过设置登录脚本的方式让用户登录时运行脚本中的软件安装程序以达到预期目的.具体方法 ...

  7. 如何在Eclipse中自动删除尾随空格?

    这个问题分为两个部分,其中一个我已经有了答案. 如何从正在编辑的整个文件中自动删除结尾的空格? ->答案:使用AnyEdit插件 ,可以将其设置为在保存到文件时执行此操作. 如何仅从我更改的行中 ...

  8. .Net CLR 中的同步机制(一): 互斥体

    随着软硬件技术的发展,无论是在Web服务或者云计算,还是单一的应用程序,串行方式编写的软件越来越少,我们总是可以看见并行的存在.但是并行并不是适合于每一种场景,也完全不是将工作扔到线程池中排队运行那么 ...

  9. ue4加载本地版本_UE4中的本地化文本Localization Dashboard(多语言版本匹配)

    前言 UE提供了一套非常赞的本地化解决方案,为游戏开发中的多语言版本匹配提供了便利.我们只需要简单的操作和配置即可完成翻译工作,在UE的最新版本中(4.19)依旧还是试验功能,您可以在菜单的Edit– ...

  10. 配置vim在源代码中自动添加作者信息

    每个程序员都有自己心爱的代码编辑和查看工具,相信不少Linux下的程序员都喜欢用Vim,尽管Vim没有SourceInsight这种依托于桌面环境的编辑器看起来那样强大,但是Vim的高效.简洁以及强大 ...

最新文章

  1. syslog记录history历史记录
  2. Android Makefile编译流程
  3. 堆(heap)和栈(stack)
  4. 初中计算机新课标培训心得,新课标学习心得体会
  5. Intellij IDEA 重置所有工具栏 Intellij IDEA 中的 Debug 控制台输出窗口不见了的解决办法
  6. no module named numpy_nn.functional和nn.Module
  7. AI 脑补宋明清皇帝长相,四大模型构想真实五官
  8. 【新版】掩日免杀windows Defender
  9. 手机抢答器正在替代传统抢答器
  10. mac html字体设置,Mac Win 网页字体显示方案
  11. 阿里p7java什么水平_转头条:阿里p7架构师:三年经验应该具备什么样的技能?
  12. 美团智能配送系统的运筹优化实战-笔记
  13. 复制英文和中文PDF文字到word并去除回车符
  14. IP、MAC地址,交换机路由器,ARP、NAT协议串讲
  15. 2008年中国电子商务十大时刻
  16. 原生javascript对话框 --- sy_dialog
  17. alipay本地jar安装
  18. 【leetcode】青蛙跳楼梯问题
  19. 1、snaker笔记
  20. 每月 5 号发工资和 25 号发工资,真能看出公司是否靠谱?

热门文章

  1. ACL'22 | 关系抽取和NER等论文分类整理
  2. 聊聊我在美团做算法的感受
  3. 刚刚!腾讯宣布扩招8000人,算法岗成最大亮点!
  4. 【NLP】近期必读ICLR 2021相关论文
  5. 【学术分享】推荐一个免费下载外文文献的网站
  6. Highway Networks
  7. 30+岁、没转管理、加不动班,我的竞争力从哪里来?
  8. EventThread线程对VSync的接收
  9. 2.1 Hadoop概述
  10. Linux学习笔记(七):Shell与Shell Script