Dela via


Processbaserad körning sida vid sida

Kommentar

Den här artikeln är specifik för .NET Framework. Det gäller inte för nyare implementeringar av .NET, inklusive .NET 6 och senare versioner.

Från och med .NET Framework 4 kan du använda processervering sida vid sida för att köra flera versioner av CLR (Common Language Runtime) i en enda process. Som standard körs hanterade COM-komponenter med den .NET Framework-version som de skapades med, oavsett vilken .NET Framework-version som läses in för processen.

Bakgrund

.NET Framework har alltid tillhandahållit sida vid sida-värd för hanterade kodprogram, men före .NET Framework 4 tillhandahöll det inte den funktionen för hanterade COM-komponenter. Tidigare körde hanterade COM-komponenter som lästes in i en process antingen med den version av körningen som redan har lästs in eller med den senaste installerade versionen av .NET Framework. Om den här versionen inte var kompatibel med COM-komponenten skulle komponenten misslyckas.

.NET Framework 4 tillhandahåller en ny metod för sida-vid-sida-värd som säkerställer följande:

  • Installation av en ny version av .NET Framework påverkar inte befintliga program.

  • Program körs mot den version av .NET Framework som de skapades med. De använder inte den nya versionen av .NET Framework om de inte uttryckligen instrueras att göra det. Det är dock enklare för program att övergå till att använda en ny version av .NET Framework.

Effekter på användare och utvecklare

  • Slutanvändare och systemadministratörer. Dessa användare kan nu ha större förtroende för att när de installerar en ny version av körningen, antingen oberoende eller med ett program, kommer det inte att påverka deras datorer. Befintliga program fortsätter att köras som tidigare.

  • Programutvecklare. Sida vid sida-värd har nästan ingen effekt på programutvecklare. Som standard körs program alltid mot den version av .NET Framework som de byggdes på. detta har inte ändrats. Utvecklare kan dock åsidosätta det här beteendet och dirigera programmet att köras under en nyare version av .NET Framework (se scenario 2).

  • Biblioteksutvecklare och konsumenter. Sida vid sida-värd löser inte de kompatibilitetsproblem som biblioteksutvecklare står inför. Ett bibliotek som läses in direkt av ett program – antingen via en direktreferens eller via ett Assembly.Load anrop – fortsätter att använda körningen AppDomain av det som läses in i. Du bör testa dina bibliotek mot alla versioner av .NET Framework som du vill stödja. Om ett program kompileras med .NET Framework 4-körningen men innehåller ett bibliotek som har skapats med en tidigare körning använder biblioteket även .NET Framework 4-körningen. Men om du har ett program som har skapats med en tidigare körning och ett bibliotek som har skapats med .NET Framework 4 måste du tvinga programmet att även använda .NET Framework 4 (se scenario 3).

  • Utvecklare av hanterade COM-komponenter. Tidigare kördes hanterade COM-komponenter automatiskt med den senaste versionen av körningen som installerats på datorn. Nu kan du köra COM-komponenter mot den version av körningen som de skapades med.

    Som du ser i följande tabell kan komponenter som har skapats med .NET Framework version 1.1 köras sida vid sida med version 4-komponenter, men de kan inte köras med komponenterna version 2.0, 3.0 eller 3.5, eftersom det inte finns någon separat värd för dessa versioner.

    .NET Framework-version 1,1 2.0 - 3.5 4
    1,1 Inte tillämpligt Nej Ja
    2.0 - 3.5 Nej Inte tillämpligt Ja
    4 Ja Ja Inte aktuellt

Kommentar

.NET Framework-versionerna 3.0 och 3.5 skapas stegvis på version 2.0 och behöver inte köras sida vid sida. Dessa är i sig samma version.

Vanliga värdscenarier sida vid sida

  • Scenario 1: Internt program som använder COM-komponenter som skapats med tidigare versioner av .NET Framework.

    .NET Framework-versioner installerade: .NET Framework 4 och alla andra versioner av .NET Framework som används av COM-komponenterna.

    Vad du ska göra: I det här scenariot gör du ingenting. COM-komponenterna körs med den version av .NET Framework som de har registrerats med.

  • Scenario 2: Hanterat program som skapats med .NET Framework 2.0 SP1 som du föredrar att köra med .NET Framework 2.0, men som är villiga att köras på .NET Framework 4 om version 2.0 inte finns.

    .NET Framework-versioner installerade: En tidigare version av .NET Framework och .NET Framework 4.

    Vad du ska göra: I programkonfigurationsfilen i programkatalogen använder du <startelementet> och det <körtidselement> som stöds enligt följande:

    <configuration>
      <startup >
        <supportedRuntime version="v2.0.50727" />
        <supportedRuntime version="v4.0" />
      </startup>
    </configuration>
    
  • Scenario 3: Internt program som använder COM-komponenter som skapats med tidigare versioner av .NET Framework som du vill köra med .NET Framework 4.

    .NET Framework-versioner installerade: .NET Framework 4.

    Vad du ska göra: I programkonfigurationsfilen i programkatalogen använder du elementet <startup>useLegacyV2RuntimeActivationPolicy med attributet inställt på true och elementuppsättningen <supportedRuntime> på följande sätt:

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

Exempel

I följande exempel visas en ohanterad COM-värd som kör en hanterad COM-komponent med hjälp av den version av .NET Framework som komponenten kompilerades för att använda.

Kompilera och registrera följande hanterade COM-komponent med hjälp av .NET Framework 3.5 för att köra följande exempel. Om du vill registrera komponenten går du till menyn Projekt , klickar på Egenskaper, klickar på fliken Skapa och markerar sedan kryssrutan Registrera för COM-interop .

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);
        }
    }
}

Kompilera följande ohanterade C++-program, som aktiverar COM-objektet som skapas av föregående exempel.

#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;
}

Se även