Delen via


Uitvoering naast elkaar

Notitie

Dit artikel is specifiek voor .NET Framework. Dit geldt niet voor nieuwere implementaties van .NET, waaronder .NET 6 en nieuwere versies.

Vanaf .NET Framework 4 kunt u in-process side-by-side hosting gebruiken om meerdere versies van de Common Language Runtime (CLR) in één proces uit te voeren. Beheerde COM-onderdelen worden standaard uitgevoerd met de .NET Framework-versie waarmee ze zijn gebouwd, ongeacht de .NET Framework-versie die voor het proces is geladen.

Achtergrond

Het .NET Framework biedt altijd side-by-side hosting voor beheerde codetoepassingen, maar voordat .NET Framework 4, biedt het niet die functionaliteit voor beheerde COM-onderdelen. In het verleden werden beheerde COM-onderdelen die in een proces zijn geladen, uitgevoerd met de versie van de runtime die al is geladen of met de meest recente geïnstalleerde versie van .NET Framework. Als deze versie niet compatibel is met het COM-onderdeel, mislukt het onderdeel.

.NET Framework 4 biedt een nieuwe benadering voor side-by-side hosting die het volgende garandeert:

  • Het installeren van een nieuwe versie van .NET Framework heeft geen invloed op bestaande toepassingen.

  • Toepassingen worden uitgevoerd op basis van de versie van .NET Framework waarmee ze zijn gebouwd. Ze maken geen gebruik van de nieuwe versie van .NET Framework, tenzij ze uitdrukkelijk worden omgeleid om dit te doen. Het is echter eenvoudiger voor toepassingen om over te stappen op een nieuwe versie van .NET Framework.

Effecten op gebruikers en ontwikkelaars

  • Eindgebruikers en systeembeheerders. Deze gebruikers kunnen nu meer vertrouwen hebben dat wanneer ze een nieuwe versie van de runtime installeren, onafhankelijk of met een toepassing, dit geen invloed heeft op hun computers. Bestaande toepassingen worden nog steeds uitgevoerd zoals voorheen.

  • Toepassingsontwikkelaars. Side-by-side hosting heeft bijna geen effect op toepassingsontwikkelaars. Standaard worden toepassingen altijd uitgevoerd op basis van de versie van .NET Framework waarop ze zijn gebouwd; dit is niet veranderd. Ontwikkelaars kunnen dit gedrag echter negeren en de toepassing omsturen om te worden uitgevoerd onder een nieuwere versie van .NET Framework (zie scenario 2).

  • Bibliotheekontwikkelaars en consumenten. Hosting naast elkaar lost de compatibiliteitsproblemen die bibliotheekontwikkelaars ondervinden niet op. Een bibliotheek die rechtstreeks door een toepassing wordt geladen (via een directe verwijzing of via een Assembly.Load aanroep), blijft de runtime van de AppDomain bibliotheek gebruiken die in wordt geladen. U moet uw bibliotheken testen op alle versies van .NET Framework die u wilt ondersteunen. Als een toepassing wordt gecompileerd met behulp van de .NET Framework 4-runtime, maar een bibliotheek bevat die is gebouwd met een eerdere runtime, gebruikt die bibliotheek ook de .NET Framework 4-runtime. Als u echter een toepassing hebt die is gebouwd met een eerdere runtime en een bibliotheek die is gebouwd met .NET Framework 4, moet u afdwingen dat uw toepassing ook .NET Framework 4 gebruikt (zie scenario 3).

  • Ontwikkelaars van beheerde COM-onderdelen. In het verleden worden beheerde COM-onderdelen automatisch uitgevoerd met behulp van de nieuwste versie van de runtime die op de computer is geïnstalleerd. U kunt nu COM-onderdelen uitvoeren op basis van de versie van de runtime waarmee ze zijn gebouwd.

    Zoals wordt weergegeven in de volgende tabel, kunnen onderdelen die zijn gebouwd met .NET Framework versie 1.1 naast versie 4-onderdelen worden uitgevoerd, maar kunnen ze niet worden uitgevoerd met versie 2.0-, 3.0- of 3.5-onderdelen, omdat hosting naast elkaar niet beschikbaar is voor deze versies.

    Versie van .NET Framework 1.1 2.0 - 3.5 4
    1.1 Niet van toepassing Nr. Ja
    2.0 - 3.5 Nee Niet van toepassing Ja
    4 Ja Ja Niet van toepassing

Notitie

.NET Framework-versies 3.0 en 3.5 zijn incrementeel gebouwd op versie 2.0 en hoeven niet naast elkaar te worden uitgevoerd. Deze zijn inherent dezelfde versie.

Algemene scenario's voor side-by-side hosting

  • Scenario 1: Systeemeigen toepassing die com-onderdelen gebruikt die zijn gebouwd met eerdere versies van .NET Framework.

    .NET Framework-versies geïnstalleerd: .NET Framework 4 en alle andere versies van .NET Framework die door de COM-onderdelen worden gebruikt.

    Wat u moet doen: In dit scenario hoeft u niets te doen. De COM-onderdelen worden uitgevoerd met de versie van het .NET Framework waarmee ze zijn geregistreerd.

  • Scenario 2: Beheerde toepassing die is gebouwd met .NET Framework 2.0 SP1 die u liever met .NET Framework 2.0 wilt uitvoeren, maar wel wilt uitvoeren op .NET Framework 4 als versie 2.0 niet aanwezig is.

    .NET Framework-versies geïnstalleerd: een eerdere versie van .NET Framework en .NET Framework 4.

    Wat moet u doen: Gebruik in het configuratiebestand van de toepassing in de toepassingsmap het <opstartelement> en het <ondersteundeRuntime-element> dat als volgt is ingesteld:

    <configuration>
      <startup >
        <supportedRuntime version="v2.0.50727" />
        <supportedRuntime version="v4.0" />
      </startup>
    </configuration>
    
  • Scenario 3: Systeemeigen toepassing die com-onderdelen gebruikt die zijn gebouwd met eerdere versies van .NET Framework die u wilt uitvoeren met .NET Framework 4.

    .NET Framework-versies geïnstalleerd: .NET Framework 4.

    Wat moet u doen: Gebruik in het toepassingsconfiguratiebestand in de toepassingsmap het <startup> element met het useLegacyV2RuntimeActivationPolicy kenmerk ingesteld op true en het <supportedRuntime> element dat als volgt is ingesteld:

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

Opmerking

In het volgende voorbeeld ziet u een niet-beheerde COM-host waarop een beheerd COM-onderdeel wordt uitgevoerd met behulp van de versie van .NET Framework die het onderdeel heeft gecompileerd voor gebruik.

Als u het volgende voorbeeld wilt uitvoeren, compileert en registreert u het volgende beheerde COM-onderdeel met .NET Framework 3.5. Als u het onderdeel wilt registreren, klikt u in het menu Project op Eigenschappen, klikt u op het tabblad Opbouwen en schakelt u het selectievakje Registreren voor COM-interoperabiliteit in.

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

Compileer de volgende niet-beheerde C++-toepassing, waarmee het COM-object wordt geactiveerd dat in het vorige voorbeeld is gemaakt.

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

Zie ook