在上一篇博客是使用官方提供的 AppHost 跑起来整个 dotnet 程序。本文告诉大家在 dotnet 程序运行到托管代码之前,所需要的 Native 部分的逻辑。包括如何寻找 dotnet 运行时,如何加载运行时和框架然后跑起来业务端的 dll 文件的逻辑
在上一篇博客告诉大家在 dotnet 的 AppHost 是如何做的,详细请看 dotnet core 应用是如何跑起来的 通过AppHost理解运行过程
那如果我想要定制运行时的寻找路径呢?在 dotnet core 应用是如何跑起来的 通过AppHost理解运行过程 只是告诉大家如何定制咱的业务端的 dll 寻找路径
阅读本文能收获
- 了解 dotnet 的执行引擎(实际没有执行引擎这个概念)是如何被启动的
- 学会一个黑科技,自定义运行时所在的文件夹
- 了解为什么 dotnet core 和 dotnet framework 不一样,不需要依赖环境安装了框架
在开始之前,需要了解什么是 dotnet host 这个概念。在运行 dotnet 程序的时候,在 windows 下需要通过 win32 的形式运行。而大家都知道,如果不开 AOT 等黑科技,咱构建输出的 dll 是 IL 中间格式的,但是可执行程序是只认机器码汇编的。如何从咱的 IL 逻辑到机器运行呢?今天咱来写这部分的逻辑,让整个 dotnet 跑起来的启动部分
需要知道,整个 dotnet 的启动机制是特别复杂的,本文只是告诉大家如何跑起来,也就是只是调用各个方法而已,细节部分我就不敢讲了
在 dotnet 里面需要先启动动态编译模块,而动态(即时)编译模块的启动运行部分(非全部)本质上是一个被构建为本机代码的一个模块,需要被 Native 的逻辑执行。而运行时本身需要在 dotnet 的托管代码执行之前热起来,运行时的启动部分代码也是一个被构建为本机代码的模块
那在咱双击一个 dotnet 应用构建出来的 exe 时,到底发生了什么?咱双击的这个 dotnet 应用构建出来的 exe 本质上是一个从模版创建的二进制文件,这是一个原本由纯 Native 构成的模版二进制文件,在咱构建 dotnet 的过程,被复制到咱的输出路径,然后通过替换二进制文件里面的占坑部分内容,完成这个二进制文件。这部分细节请看 dotnet core 应用是如何跑起来的 通过AppHost理解运行过程
而下面咱将不使用模版文件创建 dotnet 的可执行文件,而是自己写一个类似 AppHost 的应用,通过编写这个应用,可以了解在 dotnet 启动之前需要做哪些步骤
在开始之前,我推荐大家拉下我的代码到本地,通过自己更改实际修改代码可以理解整个 dotnet 的启动的 Native 部分逻辑
本文放在 github 欢迎小伙伴访问
在代码仓库里面保护了两个模块,一个就是 SampleHost.vcxproj 包含的代码,这里就是 Native 的逻辑。另一个就是 ManagedLibrary 也就是咱 C# 的托管代码。下面让我来告诉大家这个仓库可以如何玩
先进入 ManagedLibrary 文件夹,双击执行 build.bat 文件,此时将会执行 dotnet 的发布命令,可以在发布之后进入 HostWithMscoree\ManagedLibrary\bin\Debug\net5.0\win-x86\publish\
文件夹,看到发布之后的内容
现在咱准备自己写一个 AppHost 应用,这个应用将支持从其他的路径找到运行时,然后执行 ManagedLibrary.dll 的逻辑。换句话说就是咱接下来的做法就是在 C 盘创建两个文件夹,分别是 c:\lindexi\Code\HostWithMscoree\dll\
和 c:\lindexi\Code\HostWithMscoree\framework\
文件夹
将 ManagedLibrary.dll 文件复制到 c:\lindexi\Code\HostWithMscoree\dll\
文件夹
将 HostWithMscoree\ManagedLibrary\bin\Debug\net5.0\win-x86\publish\
文件夹里面除了 ManagedLibrary 相关的文件外的其他文件复制到