tnblog
首页
视频
资源
登录

.net Lib.Harmony框架学习笔记

1985人阅读 2024/7/13 19:48 总访问:3467561 评论: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

评价

net core 使用 EF Code First

下面这些内容很老了看这篇:https://www.tnblog.net/aojiancc2/article/details/5365 项目使用多层,把数据库访问...

cAPS.net 保存base64位格式的图片

publicvoidUpload() { //取出图片对应的base64位字符 stringimgBase=Request[&quot;imgBase&quot;]; //c#里边的base6...

Quartz.net实例动态改变周期调度。misfire、Cron

Quartz:Java编写的开源的任务调度作业框架 类似Timer之类定时执行的功能,但是更强大Quartz.NET:是把Quartz转成C# NuGet...

.net Windows服务发布、安装、卸载、监听脚本。服务调试

一、脚本 为方便不用每次都去写安装卸载的脚本1.安装脚本@echooff @echo开始安装【服务】 %SystemRoot%\Microsoft.NET\Fr...

c、VB.net中全角半角转换方法

///&lt;summary&gt; ///转全角的函数(SBCcase) ///&lt;/summary&gt; ///&lt;paramname=&quot;input&quot;&gt;任意字符串...

.net mvc分部页,.net core分部页

.net分部页的三种方式第一种:@Html.Partial(&quot;_分部页&quot;)第二种:@{ Html.RenderPartial(&quot;分部页&quot;);}...

C.net 配合小程序实现经过第三方服务器中转文件

某些时候,微信小程序前段上传文件的时候需要经过第三方服务器再将文件上传到客户的服务器;操作如下:1:(小程序内向中端服...

.net实现QQ邮箱发送邮件功能

1、微软已经帮我们封装好了发送邮件的类MailMessage,MailMessage类构造一些邮件信息,然后通过SmtpClient进行邮件发送。Mai...

StackExchange.Redis操作redis(net core支持)

官方git开源地址https://github.com/StackExchange/StackExchange.Redis官方文档在docs里边都是官方的文档通过nuget命令下...

windows 自带的netsh进行端口映射

使用netsh 把本地任意ip的25566端口 映射到192.168.81.234的25565端口netshinterfaceportproxyaddv4tov4listenaddress=0.0....

确保.net程序始终以管理员身份运行

usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; ...

ASP.net Timer细节处理

Timer的用法:1:本人称之为计时器,是asp.net官方的一种。用法即是计时所用 2:关于计时有很多中方式,本人学识有限,暂...

.net core 使用session

tip:net core 2.2后可以直接启用session了,不用在自己添加一次session依赖,本身就添加了使用nuget添加引用Microsoft.AspN...

通俗易懂,什么是.net?什么是.net Framework?什么是.net core?

朋友圈@蓝羽 看到一篇文章写的太详细太通俗了,搬过来细细看完,保证你对.NET有个新的认识理解原文地址:https://www.cnblo...

asp.net core2.0 依赖注入 AddTransient与AddScoped的区别

asp.net core主要提供了三种依赖注入的方式其中AddTransient与AddSingleton比较好区别AddTransient瞬时模式:每次都获取一...
这一世以无限游戏为使命!
排名
2
文章
634
粉丝
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
欢迎加群交流技术