tnblog
首页
视频
资源
登录

.net Lib.Harmony框架学习笔记

2596人阅读 2024/7/13 19:48 总访问:3657045 评论:0 收藏:0 手机
分类: .net后台框架

.netcore

.net Lib.Harmony框架学习笔记

Lib.Harmony框架介绍


Lib.Harmony 是一个用于 .NET 应用程序的库,主要用于运行时的代码修改和补丁操作。它允许开发者在不修改源代码的情况下,对已编译的 .NET 程序进行动态补丁,通过方法拦截和插入自定义代码来改变程序行为。
Harmony 支持多平台运行,包括 Windows、Linux 和 macOS,灵活性高,可以通过 IL 代码精确控制程序行为。
它在游戏开发中的 Mod 开发和企业软件的热修复及功能扩展中得到广泛应用,并拥有活跃的社区支持。


官网地址:https://www.patreon.com/pardeike

安装Lib.Harmony包


这里创建了一个控制台项目,然后进行安装Lib.Harmony

基本使用

类拦截


简单来讲对类中的某个方法进行拦截处理返回的请求。
以下面的例子为例:

  1. public class Worker
  2. {
  3. public string HandlerThings()
  4. {
  5. Console.WriteLine("调用了");
  6. return "你好";
  7. }
  8. }
  1. // 标记补丁目标类为 Worker
  2. [HarmonyPatch(typeof(Worker))]
  3. // 标记补丁目标方法为 Worker 类的 HandlerThings 方法
  4. [HarmonyPatch(nameof(Worker.HandlerThings))]
  5. public class HookWorker
  6. {
  7. /// <summary>
  8. /// 前置补丁方法,会在 HandlerThings 方法执行前调用
  9. /// </summary>
  10. public static void Prefix()
  11. {
  12. Console.WriteLine("Prefix");
  13. }
  14. /// <summary>
  15. /// 后置补丁方法,会在 HandlerThings 方法执行后调用
  16. /// </summary>
  17. public static void Postfix()
  18. {
  19. Console.WriteLine("Postfix");
  20. }
  21. /// <summary>
  22. /// 最终补丁方法,会在 HandlerThings 方法执行完毕后调用
  23. /// </summary>
  24. public static void Finalizer()
  25. {
  26. Console.WriteLine("Finalizer");
  27. }
  28. }
  1. using HarmonyLib;
  2. using LearningLibHarmony;
  3. using System.Reflection;
  4. Worker worker = new Worker();
  5. Console.WriteLine(worker.HandlerThings());
  6. // 传任意参数
  7. var harmony = new Harmony("hmy");
  8. harmony.PatchAll(Assembly.GetExecutingAssembly());
  9. Console.WriteLine();
  10. Console.WriteLine(worker.HandlerThings());


我们可以把Prefix改成bool,返回false将不会有任何返回值。
Prefix方法默认返回的true,表示需要调用原生方法,这里会将篡改的参数传入原生方法。

  1. public static bool Prefix()
  2. {
  3. Console.WriteLine("Prefix");
  4. return false;
  5. }
  1. using HarmonyLib;
  2. using LearningLibHarmony;
  3. using System.Reflection;
  4. Worker worker = new Worker();
  5. Console.WriteLine(worker.HandlerThings());
  6. // 传任意参数
  7. var harmony = new Harmony("hmy");
  8. harmony.PatchAll(Assembly.GetExecutingAssembly());
  9. Console.WriteLine();
  10. Console.WriteLine("《?》"+worker.HandlerThings());

参数篡改


更改传入的参数。

  1. public class Worker
  2. {
  3. public string HandlerThings(string instring1,string instring2)
  4. {
  5. Console.WriteLine($"调用了 参数1:{instring1} 参数2:{instring2}");
  6. return instring1+ instring2;
  7. }
  8. }
  1. // 标记补丁目标类为 Worker
  2. [HarmonyPatch(typeof(Worker))]
  3. // 标记补丁目标方法为 Worker 类的 HandlerThings 方法
  4. [HarmonyPatch(nameof(Worker.HandlerThings))]
  5. public class HookWorker
  6. {
  7. /// <summary>
  8. /// 前置补丁方法,会在 HandlerThings 方法执行前调用
  9. /// </summary>
  10. public static bool Prefix(ref string instring1,ref string instring2)
  11. {
  12. Console.WriteLine($"Prefix Get param:{instring1} {instring2} ");
  13. instring1 = "Prefix1";
  14. instring2 = "Prefix2";
  15. Console.WriteLine($"Update ====> {instring1} {instring2} ");
  16. return true;
  17. }
  18. /// <summary>
  19. /// 后置补丁方法,会在 HandlerThings 方法执行后调用
  20. /// </summary>
  21. public static void Postfix()
  22. {
  23. Console.WriteLine("Postfix");
  24. }
  25. /// <summary>
  26. /// 最终补丁方法,会在 HandlerThings 方法执行完毕后调用
  27. /// </summary>
  28. public static void Finalizer()
  29. {
  30. Console.WriteLine("Finalizer");
  31. }
  32. }
  1. using HarmonyLib;
  2. using LearningLibHarmony;
  3. using System.Reflection;
  4. Worker worker = new Worker();
  5. string mm = "mm";
  6. string ff = "ff";
  7. Console.WriteLine(worker.HandlerThings(mm,ff));
  8. // 传任意参数
  9. var harmony = new Harmony("hmy");
  10. harmony.PatchAll(Assembly.GetExecutingAssembly());
  11. Console.WriteLine();
  12. Console.WriteLine("《?》"+worker.HandlerThings(mm,ff));

WPF自定义拦截


自定义消息框

  1. public class Hmy_MessageBox
  2. {
  3. public void Hmy_Show(string messageBoxText)
  4. {
  5. MessageBox.Show(messageBoxText);
  6. }
  7. }


App中注册自动拦截

  1. public partial class App : Application
  2. {
  3. //自动拦截注册
  4. protected override void OnStartup(StartupEventArgs e)
  5. {
  6. base.OnStartup(e);
  7. var harmony = new Harmony("hmy");
  8. harmony.PatchAll(Assembly.GetExecutingAssembly());
  9. }
  10. }


自动拦截类

  1. [HarmonyPatch(typeof(Hmy_MessageBox))]
  2. [HarmonyPatch(nameof(Hmy_MessageBox.Hmy_Show))]
  3. [HarmonyPatch(new[] { typeof(string) })]
  4. public class HookHmy_MessageBox
  5. {
  6. public static bool Prefix(ref string messageBoxText)
  7. {
  8. if (!(messageBoxText == "不会更改的弹窗"))
  9. {
  10. messageBoxText = "改了";
  11. }
  12. return true;
  13. }
  14. }


在窗体MainWindow.xaml里添加两个弹出提示框的按钮:

  1. <Window x:Class="LearningLibHarmony.WpfApp1.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6. xmlns:local="clr-namespace:LearningLibHarmony.WpfApp1"
  7. mc:Ignorable="d"
  8. Title="MainWindow" Height="450" Width="800">
  9. <Grid>
  10. <Button Content="不会更改的弹窗" Width="120" Height="30" Click="Button_Click"></Button>
  11. <Button Content="何明洋" HorizontalAlignment="Left" Click="Button_Click" Margin="264,336,0,0" VerticalAlignment="Top" Height="39" Width="196"/>
  12. </Grid>
  13. </Window>
  1. public partial class MainWindow : Window
  2. {
  3. public Hmy_MessageBox _Hmy_MessageBox { get; set; }
  4. public MainWindow()
  5. {
  6. InitializeComponent();
  7. _Hmy_MessageBox = new Hmy_MessageBox();
  8. }
  9. private void Button_Click(object sender, RoutedEventArgs e)
  10. {
  11. var nowbutton = (Button)sender;
  12. _Hmy_MessageBox.Hmy_Show(nowbutton.Content.ToString());
  13. }
  14. }


欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

评价
这一世以无限游戏为使命!
排名
2
文章
657
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 : 好是好,这个对效率影响大不大哇,效率高不高
ASP.NET Core 服务注册生命周期
剑轩 : http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术