改造獨立部署(SCD)模式下.NET Core應用程序 dotnet的exe文件啟動過程


 設置一個小目標

改造前

 

改造后

 

 

獨立部署SCD模式,是指在使用dotnet publish 命令時帶上-r 參數運行時標識符(RID)。

 

目標提出原因:SCD模式下文件太亂了,很多文件在開發時大多又涉及不到,發布后如果能把文件放在一個文件夾,把自己編寫的項目的文件放在根目錄,就顯得簡略多了。沒發現改造后的文件結構看着舒服多么。

 

1、准備項目,並使用SCD模式發布文

mkdir apphost

cd apphost

dotnet new mvc

dotnet build

dotnet publish -c Release -r win10-x64 -o "c:\publish"

現在我們得到了發布后的文件,現在建立runtime文件夾,並把除配置文件外的文件都移過去,

  

bower.json                     bower的配置文件

bundleconfig.json              合並cssjs文件的配置文件

appsettings.json               項目運行參數文件

appsettings.Development.json   開發模式的項目運行參數文件

apphost.runtimeconfig.json     coreclr的配置文件

apphost.deps.json              項目程序集引用關系文件

 

 

開始執行apphost.exe

 

缺少hostfxr.dll

復制此文件過來

 

缺少hostpolicy.dll

復制此文件過來

 

看不出項目的原因吧,這是需要開始Trace,在系統環境變量添加新的系統變量COREHOST_TRACE 值設置為1

再次執行后

 

 

怎么辦,無路可走了,把錯誤命令在github上搜索上,看有結果沒

 

https://github.com/dotnet/core-setup

下載源碼,調試下程序,看問題出在哪里

這里使用2.0.0版本的源碼

 

 

 

https://github.com/dotnet/core-setup/blob/master/Documentation/building/windows-instructions.md

准備環境

win8.1系統(硬盤至少50G,不然會不夠用的)

Visual Studio 2015 Update 3

CMake

Git

PowerShell

DotNet Core SDK

 

以上是文檔說的

但是還需要准備一個 dotnet-dev-win-x64.1.0.0-rc4-004771.zip

編譯的時候,需要會提示需要這個版本的sdk,不然編譯通不過

 

環境准備好,就可以執行build.cmd了,等着吧編譯時間很長

 

編譯完成后,可以在\Bin\obj\win-x64.Debug\corehost\cli\exe\apphost目錄找到  apphost.vcxproj

 

vs2015打開

 

並把 Bin\obj\win-x64.Debug\corehost\cli\dll\hostpolicy.vcxproj

Bin\obj\win-x64.Debug\corehost\cli\dll\hostfxr.vcxproj

加入到apphost.sln解決方案中

然后改動 hostpolicy.vcxprojhostfxr.vcxproj的輸出目錄到

Bin\obj\win-x64.Debug\corehost\cli\exe\apphost\Debug

 

然后把上面改動發布的文件publish里的文件全部復制到

Bin\obj\win-x64.Debug\corehost\cli\exe\apphost\Debug文件

編譯下項目,就可以開始調試了

 

我們來整理下 apphost.exe的加載邏輯

 

corehost.app入口在這里,可以一直F11下去,直到啟動coreclr

 

 

 

 

apphost.exe 主要功能是檢查文件是否合法

corehost.app main()入口

  run() 檢查執行路徑

    is_exe_enabled_for_execution() 檢查是不是又dotnet build 編譯的文件,dotnet build編譯的時候會嵌入exe文件中一個 dll文件名的hash值,因為我們是調試生成的exe文件,所以肯定通不過hash值的檢查的,所以我們把corehost.app文件的第147行的 return StatusCode::AppHostExeNotBoundFailure; 注釋掉

    下面就是加載 hostfxr.dll文件

 

源碼邏輯驗證了上面移動文件的錯誤提示信息

 

 

 

 

hostfxr.dll  讀取runtimeconfig.json文件

hostfxr.cpp hostfxr_main()是入口

    muxer.execute()

        detect_operating_mode() libhost.app  判斷執行coreclr的模式  host_mode_t

 

 invalid = 0,

    

    muxer,          // Invoked as "dotnet.exe".

    

    standalone,     // Invoked as "appname.exe" from the application base: either "standalone" or "branded". When implementing branded exes, rename this to "apphost"

 

    split_fx        // Invoked as "corehost.exe" for xunit scenarios -- this has to be fixed by the CLI to not use this executable and this mode should not be supported.

                    // Split FX means, the host is operating like "corerun.exe" in a split location from the application base (CORE_ROOT equivalent), but it has its "hostfxr.dll"

                    // next to it.

 

 

    執行 standalone 模式

 

    parse_args_and_execute()  fx_muxer.cpp    找到runtimeconfig文件

 

    read_config_and_execute  fx_muxer.cpp     找到並讀取文件

           get_runtime_config_paths_from_app  libhost.app 找到文件

            config()  runtime_config.app       格式化文件

              ensure_parsed   runtime_config.app

 

  execute_app() 執行hostpolicy.dll

 

hostpolicy.dll 讀取deps.json文件

 

corehost_main    hostpolicy.app 入口

 

  deps_resolver_t() 格式化deps.json文件

    

    load() deps_format.cpp 讀取deps.json文件

 

    resolve_probe_paths()  deps_resolver.cpp  

 

       to_dir_path()  deps_enty.cpp  檢查文件是否存在

 

  啟動coreclr.dll

 

 

 

 

到這里就可以 找到了 to_path()方法來判斷文件是否存在,修改to_dir_path()方法來實現修改如下

 

 

但是因為asp net core 使用了DI,還需要修改 Microsoft.Extensions.DependencyModel.dll不然還是會報着不到文件

 

最后可以找到 TryResolveAssemblyPaths() AppBaseCompilationAssemblyResolver.cs

 

修改如下,

 

 

經過上面的分析,發布后,只需要替換Microsoft.Extensions.DependencyModel.dllhostpolicy.dll 兩個文件就實現了目標

 

 

 可調試文件源碼

https://github.com/xakepbean/core-setup-debug


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM