次の方法で共有


In-Process side-by-side 実行

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

.NET Framework 4 以降では、インプロセス サイド バイ サイド ホスティングを使用して、複数のバージョンの共通言語ランタイム (CLR) を 1 つのプロセスで実行できます。 既定では、マネージド COM コンポーネントは、プロセス用に読み込まれた .NET Framework のバージョンに関係なく、ビルドされた .NET Framework バージョンで実行されます。

バックグラウンド

.NET Framework では、マネージド コード アプリケーションのサイド バイ サイド ホスティングが常に提供されていますが、.NET Framework 4 より前は、マネージド COM コンポーネントに対してその機能は提供されていませんでした。 以前は、プロセスに読み込まれたマネージド COM コンポーネントは、既に読み込まれているランタイムのバージョンまたはインストールされている最新バージョンの .NET Framework のいずれかで実行されていました。 このバージョンが COM コンポーネントと互換性がない場合、コンポーネントは失敗します。

.NET Framework 4 では、次のことが保証されるサイド バイ サイド ホスティングに対する新しいアプローチが提供されます。

  • 新しいバージョンの .NET Framework をインストールしても、既存のアプリケーションには影響しません。

  • アプリケーションは、ビルドされた .NET Framework のバージョンに対して実行されます。 明示的に指示されない限り、新しいバージョンの .NET Framework は使用されません。 ただし、アプリケーションは新しいバージョンの .NET Framework を使用する方が簡単です。

ユーザーと開発者への影響

  • エンド ユーザーとシステム管理者。 これらのユーザーは、新しいバージョンのランタイムを個別にインストールするとき、またはアプリケーションを使用してインストールしても、コンピューターに影響を与えないことを確信できるようになりました。 既存のアプリケーションは、以前と同じように引き続き実行されます。

  • アプリケーション開発者。 サイド バイ サイド ホスティングは、アプリケーション開発者にほとんど影響しません。 既定では、アプリケーションは、ビルドされた .NET Framework のバージョンに対して常に実行されます。これは変更されていません。 ただし、開発者はこの動作をオーバーライドし、アプリケーションを新しいバージョンの .NET Framework で実行するように指示できます ( シナリオ 2 を参照)。

  • ライブラリ開発者とコンシューマー。 サイド バイ サイド ホスティングでは、ライブラリ開発者が直面する互換性の問題は解決されません。 直接参照または Assembly.Load 呼び出しによってアプリケーションによって直接読み込まれるライブラリは、読み込まれる AppDomain のランタイムを引き続き使用します。 サポートするすべてのバージョンの .NET Framework に対してライブラリをテストする必要があります。 アプリケーションが .NET Framework 4 ランタイムを使用してコンパイルされているが、以前のランタイムを使用してビルドされたライブラリが含まれている場合、そのライブラリでも .NET Framework 4 ランタイムが使用されます。 ただし、以前のランタイムを使用してビルドされたアプリケーションと、.NET Framework 4 を使用してビルドされたライブラリがある場合は、アプリケーションで .NET Framework 4 も強制的に使用する必要があります ( シナリオ 3 を参照)。

  • マネージド COM コンポーネント開発者。 以前は、マネージド COM コンポーネントは、コンピューターにインストールされている最新バージョンのランタイムを使用して自動的に実行されました。 これで、ビルドされたランタイムのバージョンに対して COM コンポーネントを実行できるようになりました。

    次の表に示すように、.NET Framework バージョン 1.1 でビルドされたコンポーネントは、バージョン 4 のコンポーネントと並行して実行できますが、バージョン 2.0、3.0、または 3.5 コンポーネントでは実行できません。これらのバージョンではサイド バイ サイド ホスティングを使用できないためです。

    .NET Framework のバージョン 1.1 2.0 - 3.5 4
    1.1 適用なし いいえ イエス
    2.0 - 3.5 いいえ 適用なし イエス
    4 イエス イエス 適用なし

.NET Framework バージョン 3.0 および 3.5 は、バージョン 2.0 で段階的にビルドされるため、並行して実行する必要はありません。 これらは本質的に同じバージョンです。

一般的なサイド バイ サイド ホスティング シナリオ

  • シナリオ 1: 以前のバージョンの .NET Framework でビルドされた COM コンポーネントを使用するネイティブ アプリケーション。

    インストールされている .NET Framework のバージョン: .NET Framework 4 と、COM コンポーネントによって使用される .NET Framework の他のすべてのバージョン。

    実行する操作: このシナリオでは、何も行いません。 COM コンポーネントは、登録されている .NET Framework のバージョンで実行されます。

  • シナリオ 2: .NET Framework 2.0 SP1 を使用してビルドされたマネージド アプリケーション。.NET Framework 2.0 で実行したいが、バージョン 2.0 が存在しない場合は .NET Framework 4 で実行する予定です。

    インストールされている .NET Framework のバージョン: .NET Framework と .NET Framework 4 の以前のバージョン。

    操作: アプリケーション ディレクトリのアプリケーション構成ファイルで、<startup> 要素次のように設定された <supportedRuntime> 要素を使用します。

    <configuration>
      <startup >
        <supportedRuntime version="v2.0.50727" />
        <supportedRuntime version="v4.0" />
      </startup>
    </configuration>
    
  • シナリオ 3: .NET Framework 4 で実行する .NET Framework の以前のバージョンでビルドされた COM コンポーネントを使用するネイティブ アプリケーション。

    インストールされている .NET Framework のバージョン: .NET Framework 4。

    対処方法: アプリケーション ディレクトリのアプリケーション構成ファイルで、 <startup> 要素を使用し、 useLegacyV2RuntimeActivationPolicy 属性を true に設定し、 <supportedRuntime> 要素を次のように設定します。

    <configuration>
      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" />
      </startup>
    </configuration>
    

次の例では、コンポーネントが使用するようにコンパイルされた .NET Framework のバージョンを使用して、マネージド COM コンポーネントを実行しているアンマネージ COM ホストを示します。

次の例を実行するには、.NET Framework 3.5 を使用して、次のマネージド COM コンポーネントをコンパイルして登録します。 コンポーネントを登録するには、[ プロジェクト ] メニューの [プロパティ] をクリックし、[ ビルド ] タブをクリックし、[ COM 相互運用機能の登録 ] チェック ボックスをオンにします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace BasicComObject
{
    [ComVisible(true), Guid("9C99C4B5-CA54-4c58-8988-49B6811BA53B")]
    public class MyObject : SimpleObjectModel.IPrintInfo
    {
        public MyObject()
        {
        }
        public void PrintInfo()
        {
            Console.WriteLine("MyObject was activated in {0} runtime in:\n\tAppDomain {1}:{2}", System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion(), AppDomain.CurrentDomain.Id, AppDomain.CurrentDomain.FriendlyName);
        }
    }
}

次のアンマネージ C++ アプリケーションをコンパイルします。これは、前の例で作成した COM オブジェクトをアクティブにします。

#include "stdafx.h"
#include <string>
#include <iostream>
#include <objbase.h>
#include <string.h>
#include <process.h>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    char input;
    CoInitialize(NULL) ;
    CLSID clsid;
    HRESULT hr;
    HRESULT clsidhr = CLSIDFromString(L"{9C99C4B5-CA54-4c58-8988-49B6811BA53B}",&clsid);
    hr = -1;
    if (FAILED(clsidhr))
    {
        printf("Failed to construct CLSID from String\n");
    }
    UUID id = __uuidof(IUnknown);
    IUnknown * pUnk = NULL;
    hr = ::CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,id,(void **) &pUnk);
    if (FAILED(hr))
    {
        printf("Failed CoCreateInstance\n");
    }else
    {
        pUnk->AddRef();
        printf("Succeeded\n");
    }

    DISPID dispid;
    IDispatch* pPrintInfo;
    pUnk->QueryInterface(IID_IDispatch, (void**)&pPrintInfo);
    OLECHAR FAR* szMethod[1];
    szMethod[0]=OLESTR("PrintInfo");
    hr = pPrintInfo->GetIDsOfNames(IID_NULL,szMethod, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    DISPPARAMS dispparams;
    dispparams.cNamedArgs = 0;
    dispparams.cArgs = 0;
    VARIANTARG* pvarg = NULL;
    EXCEPINFO * pexcepinfo = NULL;
    WORD wFlags = DISPATCH_METHOD ;
;
    LPVARIANT pvRet = NULL;
    UINT * pnArgErr = NULL;
    hr = pPrintInfo->Invoke(dispid,IID_NULL, LOCALE_USER_DEFAULT, wFlags,
        &dispparams, pvRet, pexcepinfo, pnArgErr);
    printf("Press Enter to exit");
    scanf_s("%c",&input);
    CoUninitialize();
    return 0;
}

こちらも参照ください