今更聞けないプラットフォーム依存アセンブリを動的にロードするにはAssembyResolve編

1.2K Views

March 25, 23

スライド概要

.NETラボ 勉強会 2023年3月セッション資料

profile-image

Microsoft MVP for Developer Technologies わんくま同盟の人で、絶滅危惧種の古き時代のISVな人。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

つづきは…16:35からです 今回も MISAO を動かしてます。 Twitter で #dotnetlab を付けた 発言を拾って画面に表示してます。 一杯書き込んでくれると嬉しいし楽しいです。 でも画面に出るまで少しタイムラグがあります。 サンプルプロジェクトは↓ https://github.com/Tocchann/AssemblyResolveSamples .NETラボ 勉強会 2023年03月

2.

自己紹介 • とっちゃん • 会社員 – わんくま同盟 • Microsoft MVP – 市販パッケージソフト開発 – ISV – 2005/10–2008/09 • Independent Software Vender • 昭和のソフトハウス • Windows SDK – 2008/10-2016/09 – 絶賛リモートワーク中 • Visual C++ – 2016/10-2018 • Visual Studio and Development Technologies – 2018• Developer Technologies https://github.com/Tocchann/ AssemblyResolveSamples .NETラボ 勉強会 2023年03月

3.

今更聞けない プラットフォーム依存アセンブ リを 動的にロードするには? AssembyResolve編 とっちゃん(高萩 俊行) Microsoft MVP for Developer Technologies Since 2005/10https://github.com/Tocchann/AssemblyResolveSamples .NETラボ 勉強会 2023年03月

4.

はじめに Windows の世界も IntPtr.Size==4 だけでは 判断できない時代になってきました 今回は動的にアセンブリをロードする方法と 実行環境を判定して動的にロードする アセンブリを解決する方法を 紹介しようと思います .NETラボ 勉強会 2023年03月

5.

お品書き • • • • • • • はじめに プロジェクト構成 アセンブリがロードされるタイミング ロードされるアセンブリを動的に解決する方法 動作状態に沿ったプラットフォームの選択方法 ビルド時にアセンブリを自動的にコピーするには まとめ .NETラボ 勉強会 2023年03月

6.

プロジェクト構成 Project Name Language Type Target Framework Platform ConsoleAppCore C# exe .NET 6.0 Any CPU CppCliDllCore C++/CLI dll .NET 6.0 x86, x64, ARM32, ARM64 CsDllCore C# dll .NET 6.0 x86, x64, ARM32, ARM64 ConsoleAppNetfx C# exe .NET Framework 4.8.1 Any CPU CppCliDll C++/CLI dll .NET Framework 4.8.1 x86, x64, ARM64 CsDll C# dll .NET Framework 4.8.1 x86, x64, ARM64 AssemblyResolveLoader C# dll .NET Standard 2.0 Any CPU .NETラボ 勉強会 2023年03月

7.
[beta]
アセンブリがロードされるタイミング

• 実際にアクセスするメソッドに入るところでロードされ
Console.WriteLine(
"Before CallTest()" );
Console.WriteLine( "Before CallTestCs()" );
る
CallTest();
private static void CallTest()
{
Console.WriteLine( "CallTest()" );
var cppClass = new CppManagedClass();
}

CallTestCs();
private static void CallTestCs()
{
Console.WriteLine( "CallTestCs()" );
var csClass = new CsClass();
}

Before CallTest()
'ConsoleAppNetfx.exe' (CLR v4.0.30319: ConsoleAppNetfx.exe): 'CppCliDll.dll' が読み込まれました。
CallTest()
CppCliDll::CppManagedClass::CppManagedClass()
Before CallTestCs()
‘ConsoleAppNetfx.exe’ (CLR v4.0.30319: ConsoleAppNetfx.exe): ‘CsDll.dll’ が読み込まれました。
CallTestCs()
CsClass.CsClass():TargetFrameworkName=.NETFramework,Version=v4.8.1, IntPtr.Size=4

.NETラボ 勉強会 2023年03月

8.

アセンブリがロードされるタイミング • 実際にアクセスするメソッドに入るところでロードされ る 実際に見てみましょう .NETラボ 勉強会 2023年03月

9.

ロードされるアセンブリを動的に解決する方法 • AppDomain.AssemblyResolve イベント – アセンブリが見つからない場合に解決の機会を与えるイベント – 自動でロードできる条件の場合ロードしてしまうため呼ばれな い • Assembly.LoadFrom メソッド – 実行可能な形式で動的にアセンブリをロードする – 相対パス指定が可能 • プロセスのベースディレクトリと同じかそのサブディレクトリ • .NET 6.0 だとカレントディレクトリからの相対パスになる – 絶対パス指定 • 実行ファイルのルートをベースにパスサーチすることで安定化 .NETラボ 勉強会 2023年03月

10.

動作状態に沿ったプラットフォームの選択方法 • IntPtr.Size – IntPtr.Size == 4 なら 32bit プロセス – IntPtr.Size == 8 なら 64bit プロセス – CPUアーキテクチャの違いは判らない • RuntimeInformation.ProcessArchitecture – – – – – 実行中のプロセスアーキテクチャ Architecture.X86 なら Intel(AMD) 32bit プロセス Architecture.X64 なら Intel(AMD) 64bit プロセス Architecture.Arm なら ARM 32bit プロセス Architecture.Arm64 なら ARM 64bit プロセス .NETラボ 勉強会 2023年03月

11.

動作状態に沿ったプラットフォームの選択方法 • RuntimeInformation.ProcessArchitecture – – – – – 実行中のプロセスアーキテクチャ Architecture.X86 なら Intel(AMD) 32bit プロセス Architecture.X64 なら Intel(AMD) 64bit プロセス Architecture.Arm なら ARM 32bit プロセス Architecture.Arm64 なら ARM 64bit プロセス .NETラボ 勉強会 2023年03月

12.

動作状態に沿ったプラットフォームの選択方法 • RuntimeInformation.ProcessArchitecture 実際に見てみましょう .NETラボ 勉強会 2023年03月

13.

ビルド時にアセンブリを自動的にコピーするには • プラットフォームごとのビルド出力のコピー処理が必要 – x86, x64, Arm64(, Arm32) • 呼び出し元は AnyCPU • .NET Core の Publish へも対応 • Directory.Build.targets の理由は… – このセッションのための特殊事情 – プロジェクトの種類が違っても同じ段取りにしたい – プロジェクトをアンロードせずに参照できるようにしたい .NETラボ 勉強会 2023年03月

14.

ビルド時にアセンブリを自動的にコピーするには • 実際の選択肢 1. PostBuildEvent で出力先にコピー • • • 内部的にバッチファイルとして展開されて実行 $(Configuration)などの MSBuild プロパティが使える 若干癖がある 2. Content として追加 • • MSBuild を直接編集する必要がある ビルドの一部として自動でコピーされる 3. MSBuild のタスクとしてコピー処理を追加 1. MSBuild の高い知識が必要 .NETラボ 勉強会 2023年03月

15.

ビルド時にアセンブリを自動的にコピーするには • Content への追加 – コピー元を一本化することで簡素化 – MSBuild の機能で増減に自動追従 <PropertyGroup> <AppendConfiguration Condition="'$(_FrameworkIdentifierForImplicitDefine)'!=''">Core</AppendConfiguration> </PropertyGroup> <ItemGroup> <Content Include="$(MSBuildThisFileDirectory)bin\$(Configuration)$(AppendConfiguration)\**\*.dll"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <Pack>false</Pack> </Content> </ItemGroup> .NETラボ 勉強会 2023年03月

16.

まとめ • AssemblyResolve は Managed Assembly 向け – おもに C++/CLI 向け – C# などで作成されたプラットフォーム別アセンブリも対応 • AnyCPU だけでは完結できないときの対策方法の一つ • ARM CPUも含めての判断が必要 • Native Assembly はまたの機会に .NETラボ 勉強会 2023年03月