次の方法で共有


.NET Framework でのサイド バイ サイド実行

この記事は .NET Framework に固有のものです。 .NET 6 以降のバージョンを含む、.NET の新しい実装には適用されません。

サイド バイ サイド実行は、同じコンピューター上で複数のバージョンのアプリケーションまたはコンポーネントを実行する機能です。 共通言語ランタイムの複数のバージョンと、ランタイムのバージョンを使用するアプリケーションとコンポーネントの複数のバージョンを、同じコンピューター上で同時に使用できます。

次の図は、同じコンピューター上で 2 つの異なるバージョンのランタイムを使用する複数のアプリケーションを示しています。 アプリケーション A、B、C はランタイム バージョン 1.0 を使用し、アプリケーション D はランタイム バージョン 1.1 を使用します。

異なるランタイム バージョンの並列実行、

.NET Framework は、共通言語ランタイムと、API 型を含むアセンブリのコレクションで構成されます。 ランタイムアセンブリと .NET Framework アセンブリは個別にバージョン管理されます。 たとえば、ランタイムのバージョン 4.0 は実際にはバージョン 4.0.319 ですが、.NET Framework アセンブリのバージョン 1.0 はバージョン 1.0.3300.0 です。

次の図は、同じコンピューター上のコンポーネントの 2 つの異なるバージョンを使用する複数のアプリケーションを示しています。 アプリケーション A と B はコンポーネントのバージョン 1.0 を使用し、Application C は同じコンポーネントのバージョン 2.0 を使用します。

コンポーネントの並列実行を示す図。

Side-by-side 実行を使用すると、アプリケーションがバインドするコンポーネントのバージョンをより詳細に制御でき、アプリケーションが使用するランタイムのバージョンをより詳細に制御できます。

並行実行の利点

Windows XP と .NET Framework より前では、アプリケーションが同じコードの互換性のないバージョンを区別できなかったため、DLL の競合が発生していました。 DLL に含まれる型情報は、ファイル名にのみバインドされていました。 アプリケーションには、DLL に含まれる型が、アプリケーションがビルドされた型と同じかどうかを知る方法はありませんでした。 その結果、コンポーネントの新しいバージョンが古いバージョンを上書きし、アプリケーションを中断する可能性があります。

サイド バイ サイド実行と .NET Framework には、DLL の競合を排除するための次の機能が用意されています。

  • 厳密な名前付きアセンブリ

    サイド バイ サイド実行では、厳密な名前のアセンブリを使用して、型情報をアセンブリの特定のバージョンにバインドします。 これにより、アプリケーションまたはコンポーネントが無効なバージョンのアセンブリにバインドできなくなります。 厳密な名前のアセンブリを使用すると、同じコンピューター上に複数のバージョンのファイルを存在させ、アプリケーションで使用することもできます。 詳細については、「Strong-Named アセンブリ」を参照してください。

  • バージョン対応のコード ストレージ。

    .NET Framework は、グローバル アセンブリ キャッシュにバージョン対応のコード ストレージを提供します。 グローバル アセンブリ キャッシュは、.NET Framework がインストールされているすべてのコンピューターに存在するコンピューター全体のコード キャッシュです。 バージョン、カルチャ、および発行元の情報に基づいてアセンブリを格納し、複数のバージョンのコンポーネントとアプリケーションをサポートします。 詳細については、「 グローバル アセンブリ キャッシュ」を参照してください。

  • 分離。

    .NET Framework を使用すると、分離して実行されるアプリケーションとコンポーネントを作成できます。 分離は、サイド バイ サイド実行の不可欠なコンポーネントです。 使用しているリソースを認識し、アプリケーションまたはコンポーネントの複数のバージョン間で確実にリソースを共有する必要があります。 分離には、バージョン固有の方法でファイルを格納することも含まれます。 分離の詳細については、「 サイド バイ サイド実行のコンポーネントを作成するためのガイドライン」を参照してください。

バージョンの互換性

.NET Framework のバージョン 1.0 と 1.1 は、互いに互換性を持つよう設計されています。 .NET Framework バージョン 1.0 でビルドされたアプリケーションはバージョン 1.1 で実行する必要があり、.NET Framework バージョン 1.1 でビルドされたアプリケーションはバージョン 1.0 で実行する必要があります。 ただし、.NET Framework のバージョン 1.1 で追加された API 機能は、.NET Framework のバージョン 1.0 では機能しないことに注意してください。 バージョン 2.0 で作成されたアプリケーションは、バージョン 2.0 でのみ実行されます。 バージョン 2.0 アプリケーションは、バージョン 1.1 以前では実行されません。

.NET Framework のバージョンは、ランタイムとそれに関連付けられている .NET Framework アセンブリ (アセンブリの統一と呼ばれる概念) で構成される単一のユニットとして扱われます。 アセンブリ バインドをリダイレクトして他のバージョンの .NET Framework アセンブリを含めることができますが、既定のアセンブリ バインドのオーバーライドは危険であり、デプロイ前に厳密にテストする必要があります。

ランタイム バージョン情報の検索

アプリケーションまたはコンポーネントがコンパイルされたランタイム バージョンと、アプリケーションが実行する必要があるランタイムのバージョンに関する情報は、2 つの場所に格納されます。 アプリケーションまたはコンポーネントをコンパイルすると、コンパイルに使用されるランタイム バージョンに関する情報がマネージド実行可能ファイルに格納されます。 アプリケーションまたはコンポーネントに必要なランタイム バージョンに関する情報は、アプリケーション構成ファイルに格納されます。

マネージド実行可能ファイルのランタイム バージョン情報

各マネージド アプリケーションとコンポーネントのポータブル実行可能 (PE) ファイル ヘッダーには、ビルドされたランタイム バージョンに関する情報が含まれています。 共通言語ランタイムは、この情報を使用して、アプリケーションが実行する必要がある最も可能性の高いランタイムのバージョンを決定します。

アプリケーション構成ファイルのランタイム バージョン情報

PE ファイル ヘッダーの情報に加えて、ランタイム バージョン情報を提供するアプリケーション構成ファイルを使用してアプリケーションをデプロイできます。 アプリケーション構成ファイルは、アプリケーション開発者によって作成され、アプリケーションに付属する XML ベースのファイルです。 <requiredRuntime><startup> セクションの要素がこのファイルに存在する場合は、ランタイムのバージョンと、アプリケーションがサポートするコンポーネントのバージョンを指定します。 また、このファイルをテストで使用して、異なるバージョンのランタイムとのアプリケーションの互換性をテストすることもできます。

COM および COM+ アプリケーションを含むアンマネージ コードには、ランタイムがマネージド コードとの対話に使用するアプリケーション構成ファイルを含めることができます。 アプリケーション構成ファイルは、COM を使用してアクティブ化するすべてのマネージド コードに影響します。 このファイルでは、サポートするランタイム バージョンとアセンブリ リダイレクトを指定できます。 既定では、マネージド コードを呼び出す COM 相互運用アプリケーションでは、コンピューターにインストールされている最新バージョンのランタイムが使用されます。

アプリケーション構成ファイルの詳細については、「 アプリの構成」を参照してください。

読み込むランタイムのバージョンの決定

共通言語ランタイムでは、次の情報を使用して、アプリケーションに読み込むランタイムのバージョンを決定します。

  • 使用可能なランタイム バージョン。

  • アプリケーションがサポートするランタイム バージョン。

サポートされているランタイム バージョン

ランタイムは、アプリケーション構成ファイルとポータブル実行可能ファイル (PE) ファイル ヘッダーを使用して、アプリケーションがサポートするランタイムのバージョンを決定します。 アプリケーション構成ファイルが存在しない場合、ランタイムは、そのバージョンが使用可能な場合、アプリケーションの PE ファイル ヘッダーで指定されたランタイム バージョンを読み込みます。

アプリケーション構成ファイルが存在する場合、ランタイムは、次のプロセスの結果に基づいて、読み込む適切なランタイム バージョンを決定します。

  1. ランタイムは、アプリケーション構成ファイルの <supportedRuntime> Element 要素 を調べます。 <supportedRuntime> 要素で指定されたサポートされているランタイム バージョンが 1 つ以上存在する場合、ランタイムは最初の <supportedRuntime> 要素で指定されたランタイム バージョンを読み込みます。 このバージョンが使用できない場合、ランタイムは次の <supportedRuntime> 要素を調べ、指定されたランタイム バージョンの読み込みを試みます。 このランタイム バージョンが使用できない場合、次の<supportedRuntime> 要素が調べられます。 サポートされているランタイム バージョンがいずれも使用できない場合、ランタイムはランタイム バージョンの読み込みに失敗し、ユーザーにメッセージを表示します (手順 3 を参照)。

  2. ランタイムは、アプリケーションの実行可能ファイルの PE ファイル ヘッダーを読み取ります。 PE ファイル ヘッダーで指定されたランタイム バージョンが使用可能な場合、ランタイムはそのバージョンを読み込みます。 指定されたランタイム バージョンが使用できない場合、ランタイムは、PE ヘッダー内のランタイム バージョンと互換性がある、Microsoft によって決定されたランタイム バージョンを検索します。 そのバージョンが見つからない場合、プロセスは手順 3 に進みます。

  3. ランタイムには、アプリケーションでサポートされているランタイム バージョンが使用できないことを示すメッセージが表示されます。 ランタイムは読み込まれません。

    レジストリ キー HKLM\Software\Microsoft\.NETFramework にある NoGuiFromShim 値を使用するか、環境変数 COMPLUS_NoGuiFromShim を使用して、このメッセージの表示を抑制できます。 たとえば、無人インストールや Windows サービスなど、通常はユーザーと対話しないアプリケーションのメッセージを抑制できます。 このメッセージ表示が抑制されると、ランタイムはイベント ログにメッセージを書き込みます。 コンピューター上のすべてのアプリケーションでこのメッセージを抑制するには、レジストリ値 NoGuiFromShim を 1 に設定します。 または、COMPLUS_NoGuiFromShim環境変数を 1 に設定して、特定のユーザー コンテキストで実行されているアプリケーションのメッセージを抑制します。

ランタイム バージョンが読み込まれた後、アセンブリ バインド リダイレクトでは、個々の .NET Framework アセンブリの別のバージョンを読み込むかどうかを指定できます。 これらのバインド リダイレクトは、リダイレクトされる特定のアセンブリにのみ影響します。

部分修飾アセンブリ名と side-by-side 実行

これらはサイド バイ サイドの問題の原因になる可能性があるため、部分的に修飾されたアセンブリ参照は、アプリケーション ディレクトリ内のアセンブリへのバインドにのみ使用できます。 コード内で部分的に修飾されたアセンブリ参照は避けてください。

コード内の部分的に修飾されたアセンブリ参照を軽減するには、アプリケーション構成ファイルの <qualifyAssembly> 要素を使用して、コードで発生する部分的に修飾されたアセンブリ参照を完全に修飾できます。 部分参照で設定されていないフィールドのみを指定するには、<qualifyAssembly> 要素を使用します。 fullName 属性にリストされているアセンブリ ID には、アセンブリ名を完全修飾するために必要なすべての情報 (アセンブリ名、公開キー、カルチャ、バージョン) が含まれている必要があります。

次の例は、 myAssemblyと呼ばれるアセンブリを完全に修飾するアプリケーション構成ファイルエントリを示しています。

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly partialName="myAssembly"
fullName="myAssembly,
      version=1.0.0.0,
publicKeyToken=...,
      culture=neutral"/>
</assemblyBinding>

アセンブリ読み込みステートメントが myAssemblyを参照するたびに、これらの構成ファイル設定により、ランタイムは部分的に修飾された myAssembly 参照を完全修飾参照に自動的に変換します。 たとえば、Assembly.Load("myAssembly") は Assembly.Load("myAssembly, version=1.0.0.0, publicKeyToken=..., culture=neutral") になります。

LoadWithPartialName メソッドを使用すると、部分的に参照されるアセンブリがグローバル アセンブリ キャッシュから読み込まれないようにする共通言語ランタイム制限をバイパスできます。 このメソッドは、サイド バイ サイド実行で問題を簡単に引き起こす可能性があるため、リモート処理シナリオでのみ使用する必要があります。

タイトル 説明
方法: 自動バインド リダイレクト を有効または無効にする アプリケーションをアセンブリの特定のバージョンにバインドする方法について説明します。
アセンブリ バインド リダイレクトの構成 アセンブリ バインド参照を特定のバージョンの .NET Framework アセンブリにリダイレクトする方法について説明します。
インプロセス side-by-side 実行 インプロセス のサイド バイ サイド ランタイム ホストのアクティブ化を使用して、1 つのプロセスで複数のバージョンの CLR を実行する方法について説明します。
.NETでのアセンブリ アセンブリの概念的な概要を提供します。
アプリケーション ドメイン アプリケーション ドメインの概念の概要を説明します。

リファレンス

<supportedRuntime> 要素