本文在上一篇文章的基础上继续操作:
dnSpy调试工具二次开发1-新增菜单-CSDN博客
经过阅读dnSpy的源码,发现dnSpy使用到的依赖注入用了MEF框架,所以在源码中可以看到接口服务类的上面都打上了Export的特性或在构造方法上面打上ImportingConstructor特性,如下图:
我是从以下几个类找到了该如何写日志到控制台的蛛丝马迹:
dnSpy项目Text\Editor\Editor目录下的类:LogEditor.cs
dnSpy.Debugger项目下的ToolWindows\Logger目录下的类OutputLogger.cs
在LogEditor.cs的这三个地方打上断点
启动visual studio调试,然后运行dnSpy程序后,在dnSpy程序中附加一个程序到进程,然后就会进入到上面的断点,如下图:
我是仿照类OutputLogger.cs中的Initialize_UI方法中的最后一行代码进行写日志到控制台操作的,如下图:
好了,方法都告诉你了,其它的就只能靠你自己看源码了,本文的主题内容正式开始:
在上一篇博文中,我们已经实现了添加菜单,本文在NewTestScreen类的基础上操作,编辑该类如下:
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using dnSpy.Contracts.Debugger;
using dnSpy.Contracts.Menus;
using dnSpy.Contracts.Output;
using dnSpy.Contracts.Text;
using dnSpy.Output;
using Microsoft.VisualStudio.Utilities;namespace dnSpy.MainApp {[ExportMenuItem(OwnerGuid = MenuConstants.APP_MENU_NEW_GUID, Header = "res:Menu_TestNew", Group = MenuConstants.GROUP_APP_MENU_TEST_NEW, Order = MenuConstants.ORDER_APP_MENU_NEW)]class NewTestScreen : MenuItemBase {public readonly Guid GUID_OUTPUT_LOGGER_DEBUG = new Guid("7B6E802A-B58C-4689-877E-3358FCDCEFAC");readonly Lazy<IOutputService> outputService;readonly Lazy<IContentTypeRegistryService> contentTypeRegistryService;IOutputTextPane? textPane;[ImportingConstructor]public NewTestScreen(Lazy<IOutputService> outputService, Lazy<IContentTypeRegistryService> contentTypeRegistryService) {this.outputService = outputService;this.contentTypeRegistryService = contentTypeRegistryService;}public override void Execute(IMenuItemContext context) {textPane = outputService.Value.Create(GUID_OUTPUT_LOGGER_DEBUG, "调试", contentTypeRegistryService.Value.GetContentType(ContentTypes.OutputDebug));textPane.WriteLine(BoxedTextColor.DebugLogMDA, "测试日志输出");}}
}
我们在NewTestScreen类的构造器中注入:Lazy<IOutputService> outputService和 Lazy<IContentTypeRegistryService> contentTypeRegistryService接口,这两个接口框架会在创建NewTestScreen对象时自动注入,这种依赖注入方式叫构造器注入,和依赖注入框架
Microsoft.Extensions.DependencyInjection的构造器注入有着神奇的相似。
NewTestScreen类Execute方法的outputService.Value.Create获取到写日志到控制台的接口,就是借鉴了类OutputLogger.cs中的Initialize_UI方法中的
outputService.Value.Create(GUID_OUTPUT_LOGGER_DEBUG, dnSpy_Debugger_Resources.DebugLoggerName, contentTypeRegistryService.Value.GetContentType(ContentTypes.OutputDebug));
生成dnSpy项目,并点击dnSpy的"测试新增"菜单,可以看到成功输出了日志到dnSpy的控制台
好了,本文的内容到此结束