.NET Frameworkの周辺(2)
.NET Frameworkの内部要素
《 初回公開:2019/10/05 , 最終更新:2020/05/14 》
.NET Frameworkにおけるプログラムは次の要素で構成される。
- モジュール
- アセンブリ
- アプリケーションドメイン
- プロセス
【 目次 】
アセンブリ(assembly)
- .NET のアセンブリ | Microsoft Docs
アセンブリは、.NET ベースのアプリケーションの配置、バージョン管理、再利用、アクティベーション スコープ、およびセキュリティ権限の基本単位です。
アセンブリは、実行可能 (.exe) ファイルまたはダイナミック リンク ライブラリ (.dll) ファイルの形を取る、.NET アプリケーションの構成要素です。
それらは、型の実装に関して必要な情報を共通言語ランタイムに提供します。
アセンブリは、機能的な論理的な単位を形成し、連携して動作するように構築された、型とリソースのコレクションと考えることができます。 - アセンブリ (共通言語基盤) - Wikipedia
共通言語基盤においてアセンブリ (assembly) とはコンパイルされたコードライブラリのことであり、配置・バージョン管理・セキュリティ管理の単位となる。
…
Windowsの.NET Frameworkの実装においては、アセンブリはPE形式ファイルである。アセンブリにはプロセスアセンブリ (EXE) とライブラリアセンブリ (DLL) の二種類がある。 - アセンブリとは - IT用語辞典 e-Words
Microsoft .NETのプログラム単位
Microsoft .NETにおけるコード管理の基本単位となるコンパイル済みの実行コードをアセンブリという。
.NET標準の共通中間言語(CIL:Common Intermediate Language)で記述されたライブラリ形式(DLL)または実行可能形式(EXE)のファイルで、ソフトウェアの配置やバージョン管理、別のコードからの再利用、スコープの適用、セキュリティ管理などの単位となる。
実行時には.NET Frameworkなどの共通言語ランタイム(CLR:Common Language Runtime)により、そのプラットフォームで実行できる形式に変換され、実行される。 - IL の概要 - IL(.NET Framework の中間言語) | ++C++; // 未確認飛行 C
C#などのソース コードのコンパイル結果、つまり、.NET向けの実行可能形式(exe)やライブラリ(dll)を総称して、.NETアセンブリ(assembly)と言います。
アセンブリの中には、メタデータ(型情報や属性)と、ILコードが入っています。
…
どのクラスがどういうメンバーを持っていてとか、そういう情報が全部アセンブリ内に残る。
これはアセンブリ言語表現の IL。 実際にアセンブリに入るのは、この情報をバイナリ化したもの。 - .NETの中間言語 | C#たんっ!
C#などのソース コードのコンパイル結果、つまり、.NET向けの実行可能形式(exe)やライブラリ(dll)を総称して、.NETアセンブリ(assembly)と言います。 アセンブリの中には、以下のように、メタデータ(型情報や属性)と、ILコードが入っています。
- C#でプラグインDLLを作る方法(入門編) - Qiita
C#でいうアセンブリとは、ざっくり言うとexeかdllのことです。
実行可能なアプリケーションがexe、ライブラリがdllとなります。
C#ではすべてのライブラリがdllとしてビルドされます。
exeが実行可能であること以外は、両者にほとんど差はなく、ひっくるめてアセンブリと呼ばれることが多いです。
アセンブリとは、メタデータとILコードの集合の事
アセンブリの本来の意味は
- アセンブリの意味とは?IT用語としての使い方も解説 | TRANS.Biz
学校や地域などの「集会」「会合」、政府の「議会」などの意味を持つ言葉です。
…
もう一つの「アセンブリ」の意味は部品やパーツなどの「組み立て」です。
たとえば、パーツのみで配送された自転車やテーブルを組み立てしたり、部品をそれぞれ合わせて一つの製品として完成させるような工程が「アセンブリ」です。
これが転じて、.NET Frameworkではコンパイラーによって組み立てられたILコードとメタデータの集合の事をアセンブリというのかな。
結果的にはコンパイラー(とリンカー)の成果物であるexeファイルがdllファイルを指す事になるようだ。
コンパイラーはILコードとメタデータをマネージモジュールの中に出力する
メタデータとはモジュールの中にどのような型やメンバーなどが定義されているのかを記述したテーブル
PEファイル
.NET Frameworkの言語のコンパイラーはアセンブリをPE形式のファイルとして出力する。
ではPE形式ファイルとは
- Portable Executable - Wikipedia
Portable Executable(PE)は、主に32ビットおよび64ビット版のMicrosoft Windows上で使用される実行ファイルのファイルフォーマットである。
PEフォーマット自体はオペレーティングシステムやハードウェアに依存しない設計となっているため、UEFIアプリケーションや.NETアプリケーションのバイナリフォーマットとしても使用されている。 - PE(Portable Executable)ファイルフォーマットの概要
- PEフォーマットを解釈せよ! (1/3):リバースエンジニアリング入門(5) - @IT
- PEファイルフォーマットについて - 196Log
マネージPEファイルは主に以下の4つの部分で構成される。
- PEヘッダー
- CLRヘッダー
- メタデータ
- 中間言語IL
メタデータ
メタデータとは
-
メタデータと自己言及的なコンポーネント | Microsoft Docs
メタデータはプログラムを説明するバイナリ情報であり、共通言語ランタイムのポータブル実行可能 (PE) ファイルまたはメモリのいずれかに格納されます。
コードを PE ファイルとしてコンパイルすると、PE ファイルの特定の部分にメタデータが挿入され、コードは Microsoft Intermediate Language (MSIL) に変換されて PE ファイル内の別の部分に挿入されます。
モジュール内またはアセンブリ内で定義され、参照されているすべての型およびメンバーは、メタデータ内部に記述されます。 コードを実行すると、
ランタイムはメタデータをメモリに読み込み、コードのクラス、メンバー、継承などの情報を検索するためにメタデータを参照します。 -
インサイド .NET Framework [改訂版]第1回 マネージ・コード/アセンブリ/モジュール(2/5) - @IT
もう1つは、その実行可能コードに関する「すべて」の情報である。「すべて」とは、
プログラムには、どんな型が含まれているのか。
その中の、どれが外部に公開されているのか。
どんなローカル変数を使うのか。
どんなメソッドがどんな引数を取るのか。
プログラムは、外部のどんな型を利用するのか。
プログラムは、コンピュータに害を及ぼしかねない作業のうち、何と何を行うのか。
プログラムは、スタックのスロットをいくつ使うのか。
などなど。これらの情報は、モジュールの中にメタデータとして記述されている。
「メタデータ」は一般名詞だが、CLRでは、読み取ることができるメタデータの形式を定義しているので、ここでいうメタデータは、CLRに対して掲示するための形式で記述された情報である。
このような詳細情報を頼りに、CLRは実行可能コードを自分の管理下で実行する。
メータデータは定義,参照,マニュフェストに分ける事ができる。
マニフェスト
PEファイルにはマニュフェストと呼ばれるデータブロックが含まれている。
マニュフェストはメタデータテーブル
アセンブリを構成するファイル,それらに含まれている外部に公開されている型,アセンブリに関連付け
- .NET のアセンブリ | Microsoft Docs
- インサイド .NET Framework [改訂版]第1回 マネージ・コード/アセンブリ/モジュール(3/5) - @IT
シングル・モジュール・アセンブリでは、その単一のモジュールの中に、アセンブリに関する情報も含まれている。
アセンブリに関する情報とは、アセンブリの名前、アセンブリが外部に公開している型、アセンブリの署名を確認するための公開鍵などだ。
これらの情報は、「マニフェスト(manifest)」と呼ばれる領域に書き込まれる(manifestは「積荷目録」の意)。
...
つまりモジュールに加えて、さらにアセンブリに関する情報が含まれるわけだ。
この場合、マニフェストには、アセンブリの名前に関する情報が含まれている。
本来マニフェストには、そのアセンブリが参照する外部のアセンブリに関する情報や、そのアセンブリが外部に公開する型に関する情報が含まれるのだが、シングル・モジュール・アセンブリの場合、モジュールのメタデータにも同じ情報が書いてあるため、重複を省くために省略される。 - インサイド .NET Framework [改訂版]第1回 マネージ・コード/アセンブリ/モジュール(4/5) - @IT
マニフェストに含まれるもの
マルチ・モジュール・アセンブリを眺めると、マニフェストには何が書かれている必要があるのかが見えてくるだろう。
シングル・モジュールのときとは違い、マルチ・モジュール・アセンブリのマニフェストには、
アセンブリの名前(アイデンティティ)
アセンブリに含まれる各モジュールが参照している外部のアセンブリの情報
アセンブリに含まれる各モジュールが外部に公開している型の情報
が含まれている。まさにマニフェスト(目録)の役割を担っているわけだ。 - アプリケーション実行時に常にAdministratorとして実行する
- Windows 8.1 でバージョン判別するときの注意点 | grabacr.net
- マニフェストファイルの参照
そもそもマニフェストとは
マニフェストとは 簡単に
- 「マニフェスト」とは?意味や使い方を解説 | 意味解説
マニフェストの意味は「個人・団体が方針や意図を多数の者に向かって知らせるための文書や演説」「声明文・宣言書」それが転じた「選挙において、政党が公約に掲げる要目を発表する案内書・選挙公約」となります。
つまり、プログラムの方針や意図を知らせるためのデータという意味なのかな
Assemblyクラス
c# Assemblyクラス,C# リフレクション
.NET Frameworkにはアセンブリを示すAssemblyクラスが用意されていて、Assemblyクラスのオブジェクトを取得することにより、実行中のプログラム自身のアセンブリや他のプログラムのアセンブリをロードしてアセンブリに含まれる型情報などを取得する事ができる。
-
Assembly Class (System.Reflection) | Microsoft Docs
再利用でき、バージョン管理可能で自己記述型の共通言語ランタイム アプリケーションのビルド ブロックであるアセンブリを表します。
- 動的にDLLファイルのクラスメソッドを呼び出す (Reflectionを用いたアセンブリの動的呼び出し) (C#プログラミング)
- クラス名やアセンブリ名を取得するには?[C#/VB]:.NET TIPS - @IT
- 文字列で指定したクラスのインスタンスを作成するには? - @IT
- アセンブリを動的にロードし、そして完全にアンロードする:Gushwell's Dev Notes
- EZ-NET: プログラムからアセンブリ情報を取得する - Visual C# プログラミング
つまり、俗に言うリフレクションの操作をおこなう事ができる。
AssemblyInfo.cs
プロジェクトのプロパティにアセンブリ情報やバージョンを設定することができる。
この情報はAssemblyInfo.csに記述される。
- C#でAssemblyInfo.csにアセンブリ情報を設定、Visual Studioでバージョン情報やプロパティを入れる方法 | urashita.com 浦下.com (ウラシタドットコム)
- [C#] アセンブリ情報やバージョンを取得する - ざこノート
AssemblyInfo.csに記述された情報はAssemblyクラス等を通して取得できる。
AssemblyInfoクラス
Assemblyクラスと似たような名前のクラス、AssemblyInfoクラスがMicrosoft.VisualBasic.ApplicationServicesおよびSystem.Web.Configuration名前空間に定義されている。
- AssemblyInfo Class (Microsoft.VisualBasic.ApplicationServices) | Microsoft Docs
- AssemblyInfo Class (System.Web.Configuration) | Microsoft Docs
モジュール
モジュールとアセンブリの関係
- インサイド .NET Framework [改訂版]第1回 マネージ・コード/アセンブリ/モジュール(2/5) - @IT
ILとメタデータは、.NET Frameworkにおける「モジュール」の中に書き込まれる。
モジュールとは、Win32の世界で一般に使われている、PE(Portable Executable)形式のファイル、またはそのインメモリ・データである*2。
プログラムの実行時、CLRは、(最終的には)モジュールをロードして、ILとメタデータを読み込む。
モジュールを作る方法は、これまでと同じで、プログラム・ソースをコンパイルすることである。
...
Windowsから見れば実行可能(PE)な形式であるモジュールだが、残念ながらCLRはモジュールを直接ロードすることはできない。
...
CLRはモジュールではなくアセンブリをロードし、実行する。
...
アセンブリとは、複数のモジュールがまとまったものである。
モジュールは、物理的なファイルやインメモリのデータ、つまり具体的なビット・データを表している。
一方アセンブリは、複数の物理的なモジュールをまとめる論理的な情報である。アセンブリそのものには実体がない。
マルチ・モジュール・アセンブリ
- インサイド .NET Framework [改訂版]第1回 マネージ・コード/アセンブリ/モジュール(3/5) - @IT
このように、.NET Framework 1.1 SDKに標準で付属する5つのコンパイラは、どれもモジュールを作り出せると同時に、アセンブリも作り出すことができる。
C#などの場合、targetオプションをmoduleに設定した場合だけ、モジュールのみが作成されることになる(ただしJScript .NETのコンパイラでは、moduleは指定できない)。 - インサイド .NET Framework [改訂版]第1回 マネージ・コード/アセンブリ/モジュール(4/5) - @IT
マルチ・モジュール・アセンブリの作成
いま述べたシングル・モジュール・アセンブリに対し、複数のモジュールを1つのアセンブリとして構成したものは「マルチ・モジュール・アセンブリ」と呼ばれる。
例えば、CやC++でコードを書いてコンパイルすると、objファイルが出来上がり、このobjファイルと、ほかのobjファイルやlibファイルをリンクすると、実行可能ファイル(exeやdll)が出来上がる。
それと同様に、ソース・コードをコンパイルして、モジュールを作り、出来上がったモジュールを複数リンクしてアセンブリを作ることができるのだ。
ただし残念ながら、現行のVisual Studio .NET(以下VS .NET)でC#やVB.NETのプロジェクトを利用する限り、マルチ・モジュール・アセンブリは作れない。VS .NETは、1つのプロジェクトをシングル・モジュール・アセンブリとして構成する。
ほかのアセンブリを参照することはできるが、ほかのモジュールをアセンブリに取り込むことはできない。
このためマルチ・モジュール・アセンブリを作るには、コマンドライン・コンパイラを使う必要がある。
逆にいえば、VS .NETがなくても、SDK(.NET Framework SDK)だけで十分この作業ができることになる。
...
モジュールをアセンブリにするには2つ方法がある。
1つはコンパイラを使う方法、もう1つはアセンブリ・リンカ(al.exe)を使う方法である。
コンパイラを使う方法は、複数のモジュールと、まだコンパイルされていないソース・コードがあるときに利用できる。vbc.exeとcsc.exeには、/addmoduleというオプションがある。
...
従来のobjファイルやlibファイルをリンクして作る実行可能ファイルとは違い、アセンブリには複数の物理的なファイルが含まれる。
従って上記のコマンドを実行しても、mainmod.dllにmylib.netmoduleの中身が取り込まれるわけではない。あくまでも独立した物理ファイルとして存在しつつ、アセンブリとしては論理的にひとかたまりのコードとして存在するということになるのだ。
前述したとおり、モジュールは物理的な存在であり、アセンブリは論理的存在なのである。 -
al /t:library assem1.netmodule assem2.netmodule /out:new.dll
にして、2つのDLLを1つにできると考えましたが間違いでした。
このコマンドは、new.dll に、2つの .netmodule のファイル名を記録するだけでした。
実行には、.netmodule ファイルが必要です。
この情報にパスは含まれないので、配置を変更する目的にも使用できません。 - 方法: マルチファイル アセンブリをビルドする | Microsoft Docs
Moduleクラス
- Module Class (System.Reflection) | Microsoft Docs
モジュールのリフレクションを実行します。
アセンブリもモジュールもメタデータを含んでいるPE形式のファイル、ではアセンブリとモジュールの違いは何だろう。
CLRはモジュールではなくアセンブリを実行する。
つまりモジュールはPE形式のファイルであるにも関わらずそれ単独では実行できない。
アセンブリは一つ以上のマネージモジュールとリソースファイルの論理的集合
アセンブリは再利用、セキュリティ、バージョン管理における最小単位
アセンブリは複数のファイルをグループ化する手段
通常、一つのアセンブリには一つのモジュールが含まれるが、
マルチ・モジュール・アセンブリといって、複数のモジュールを含んだアセンブリを作成する事もできる。
VisualStudioIDEを使ってマルチ・モジュール・アセンブリの作成する事はできない。
マルチ・モジュール・アセンブリの作成するためには、コンパイラを使う方法とアセンブリリンカー(al.exe)使う方法がある。
アプリケーション ドメイン - AppDomainクラス
アプリケーション ドメイン
Windowsでは、一つ一つのプロセスが専用の仮想アドレス空間を持っている
通常、一つのプロセスの中では一つのアプリケーションを実行する。
複数のアプリケーションを実行する事はできない。
ところが、.NET FrameworkのアプリケーションのコードはCLRによって管理されているsafeなコードなので、.NET Framework(のCLR)は単一のOSプロセスの中で複数のマネージアプリケーションを実行する事ができる
この時一つ一つのアプリケーションの事をAppDomainと呼ぶ。
デフォルトでは、すべてのマネージexeが一つのAppDomainを持つ別々のアドレス空間で動作する。
CLRをホスティングするプロセスによっては単一のOSプロセスで複数のAppDomainを実行するものもある。
一つのプロセスの中で複数のアプリケーションを実行する事で、リソースの消費を抑えパフォーマンスを改善する事ができる。
- 連載 明解.NETテクノロジ アプリケーション・ドメイン Application Domain(1/2) - @IT
アプリケーション・ドメインとは、共通言語ランタイム(CLR)における、実行コードの管理単位である。
従来のWindowsにおけるプロセスに相当する。アプリケーション・ドメインの機能は、AppDomainクラス(System名前空間)を介して外部に公開されている。 - 連載 明解.NETテクノロジ アプリケーション・ドメイン Application Domain(2/2) - @IT
1つのプロセスの中に複数の「アプリケーション」をロードし、実行する機能を提供することにした。
...
依然として、共通言語ランタイム上で動作するアプリケーションにも、個別にセキュリティを設定できる機能が必要である。
そこで、共通言語ランタイムでは、共通言語ランタイム版プロセスとでもいうべき機能が導入された。
それが「アプリケーション・ドメイン」である。
アプリケーション・ドメインは、共通言語ランタイム上で利用される型やセキュリティを管理する単位である。
...
C#のプログラムをコンパイルして実行すると、そのコードはデフォルトのアプリケーション・ドメイン内部で実行される。
...
現在コードが実行されているアプリケーション・ドメインを取得したい場合は、次のコードを記述する。
System.AppDomain ad = System.AppDomain.CurrentDomain;
...
System.AppDomain ad
= System.AppDomain.CreateDomain("子ドメイン");
ad.ExecuteAssembly("app2.exe");
...
このように共通言語ランタイムでは、1つのプロセスの内部で複数の「アプリケーション」を動作させることができる。
アプリケーション・ドメインは、共通言語ランタイム上で動作するアプリケーションにとってのプロセス空間なのである。 - アプリケーションが実行される分離環境を使う(AppDomainクラス) | 日経 xTECH(クロステック)
アプリケーションが実行される分離環境の「アプリケーション・ドメイン」を表すのがAppDomainクラスである。
アプリケーション・ドメインを使うと,プロセスの停止を引き起こす可能性のあるタスクを分離できる。
...
この仕組みを利用すると,大きなDLLを使い,長時間実行されるプロセスの使用メモリー容量を最小限に抑えられる。 - AppDomain:Gushwell's Dev Notes
- アプリケーション ドメインとアセンブリを使用したプログラミング | Microsoft Docs
AppDomainクラス
- AppDomain Class (System) | Microsoft Docs
-
うらぶろぐ @urasandesu: 二つの AppDomain の狭間で - I wish we human would be gatekeepers of CLR... -
- アセンブリを動的にロードし、そして完全にアンロードする:Gushwell's Dev Notes
AppDomainクラスを利用する事で、他のアプリケーション(アセンブリ)をロードして実行したり,他のアプリケーションのアセンブリ情報を取得、使い終わったアプリケーションをアンロードしたりする事ができる。
アセンブリの参照
.NET Frameworkのアプリケーションが他のアセンブリを参照するには
DLLの検索順
DLLを参照するには
c# csc.rsp -reference
コンパイラがアセンブリを参照するには
- .NET TIPS コンパイラによりデフォルトで参照されるアセンブリは? - C# VB.NET - @IT
- .NETのLibrary(Assembly)のファイル名をどっかからひっぱる方法についてメモ - quwaharaの日記(旧)
グローバル アセンブリ キャッシュ(GAC)
共通で利用するアセンブリを参照するには
- 解説:インサイド .NET Framework 第4回 アセンブリのロード(前編)(3/3) - @IT
グローバル・アセンブリ・キャッシュ(GAC)とは、名前のとおりマシン全体でグローバルに参照可能なアセンブリの配置場所だ。
- GAC(グローバル・アセンブリ・キャッシュ)からファイルを取り出すには? - @IT
- グローバルアセンブリキャッシュにアセンブリをインストールする - .NET Tips (VB.NET,C#...)
- GAC 内のアセンブリ検索方法 | C#.NET vs VB.NET
- 方法: アセンブリをグローバル アセンブリ キャッシュにインストールする | Microsoft Docs
- プログラミング Microsoft .NET Framework - 第 3 章 共有アセンブリ | Microsoft Docs