Bagikan melalui


Eksekusi Berdampingan Dalam Proses

Catatan

Artikel ini khusus untuk .NET Framework. Ini tidak berlaku untuk implementasi .NET yang lebih baru, termasuk .NET 6 dan versi yang lebih baru.

Dimulai dengan .NET Framework 4, Anda dapat menggunakan hosting berdampingan dalam proses untuk menjalankan beberapa versi runtime bahasa umum (CLR) dalam satu proses. Secara default, komponen COM terkelola dijalankan dengan versi .NET Framework yang dibuatnya, terlepas dari versi .NET Framework yang dimuat untuk proses tersebut.

Latar belakang

.NET Framework selalu menyediakan hosting berdampingan untuk aplikasi kode terkelola, tetapi sebelum .NET Framework 4, ini tidak menyediakan fungsionalitas tersebut untuk komponen COM terkelola. Di masa lalu, komponen COM terkelola yang dimuat ke dalam proses berjalan baik dengan versi runtime yang sudah dimuat atau dengan versi terbaru .NET Framework yang diinstal. Jika versi ini tidak kompatibel dengan komponen COM, komponen akan gagal.

.NET Framework 4 menyediakan pendekatan baru untuk hosting berdampingan yang memastikan hal berikut:

  • Menginstal versi baru .NET Framework tidak berpengaruh pada aplikasi yang sudah ada.

  • Aplikasi berjalan terhadap versi .NET Framework yang digunakan untuk membangunnya. Aplikasi tersebut tidak menggunakan versi baru .NET Framework kecuali secara tegas diarahkan untuk melakukannya. Namun, lebih mudah bagi aplikasi untuk bertransisi menggunakan versi baru .NET Framework.

Efek pada Pengguna dan Pengembang

  • Pengguna akhir dan administrator sistem. Pengguna ini sekarang dapat memiliki keyakinan yang lebih besar bahwa ketika mereka menginstal versi baru runtime, baik secara mandiri maupun dengan aplikasi, itu tidak akan berdampak pada komputer mereka. Aplikasi yang ada akan terus berjalan seperti sebelumnya.

  • Pengembang aplikasi. Hosting berdampingan hampir tidak berpengaruh pada pengembang aplikasi. Secara default, aplikasi selalu berjalan terhadap versi .NET Framework tempatnya dibuat; ini tidak berubah. Namun, pengembang dapat mengambil alih perilaku ini dan mengarahkan aplikasi untuk berjalan di bawah versi .NET Framework yang lebih baru (lihat skenario 2).

  • Pengembang dan konsumen pustaka. Hosting berdampingan tidak menyelesaikan masalah kompatibilitas yang dihadapi pengembang pustaka. Pustaka yang dimuat langsung oleh aplikasi -- baik melalui referensi langsung atau melalui panggilan Assembly.Load -- terus menggunakan runtime AppDomain tempat aplikasi dimuat. Anda harus menguji pustaka Anda terhadap semua versi .NET Framework yang ingin Anda dukung. Jika aplikasi dikompilasi menggunakan runtime .NET Framework 4 tetapi menyertakan pustaka yang dibuat menggunakan runtime sebelumnya, pustaka tersebut akan menggunakan runtime .NET Framework 4 juga. Namun, jika Anda memiliki aplikasi yang dibuat menggunakan runtime sebelumnya dan pustaka yang dibuat menggunakan .NET Framework 4, Anda harus memaksa aplikasi untuk juga menggunakan .NET Framework 4 (lihat skenario 3).

  • Pengembang komponen COM terkelola. Di masa lalu, komponen COM terkelola secara otomatis berjalan menggunakan versi terbaru dari runtime yang diinstal pada komputer. Anda sekarang dapat menjalankan komponen COM terhadap versi runtime yang dibangun.

    Seperti yang ditunjukkan oleh tabel berikut, komponen yang dibangun dengan .NET Framework versi 1.1 dapat berjalan berdampingan dengan komponen versi 4, tetapi tidak dapat berjalan dengan komponen versi 2.0, 3.0, atau 3.5, karena hosting berdampingan tidak tersedia untuk versi tersebut.

    Versi .NET Framework 1.1 2.0 - 3.5 4
    1.1 Tidak berlaku Tidak Ya
    2.0 - 3.5 No Tidak berlaku Ya
    4 Ya Ya Tidak berlaku

Catatan

.NET Framework versi 3.0 dan 3.5 dibuat secara bertahap pada versi 2.0, dan tidak perlu dijalankan berdampingan. Ini pada dasarnya adalah versi yang sama.

Skenario Hosting Berdampingan yang Umum

  • Skenario 1: Aplikasi asli yang menggunakan komponen COM yang dibuat dengan versi .NET Framework yang lebih lama.

    Versi .NET Framework diinstal: .NET Framework 4 dan semua versi lain dari .NET Framework yang digunakan oleh komponen COM.

    Apa yang harus dilakukan: Dalam skenario ini, jangan lakukan apa pun. Komponen COM akan berjalan dengan versi .NET Framework yang didaftarkan.

  • Skenario 2: Aplikasi terkelola yang dibangun dengan .NET Framework 2.0 SP1 yang ingin Anda jalankan dengan .NET Framework 2.0, tetapi bersedia dijalankan pada .NET Framework 4 jika versi 2.0 tidak ada.

    Versi .NET Framework diinstal: Versi .NET Framework dan .NET Framework 4 yang lebih lama.

    Apa yang harus dilakukan: Dalam file konfigurasi aplikasi di direktori aplikasi, gunakan elemen <startup> dan elemen <supportedRuntime> yang diatur sebagai berikut:

    <configuration>
      <startup >
        <supportedRuntime version="v2.0.50727" />
        <supportedRuntime version="v4.0" />
      </startup>
    </configuration>
    
  • Skenario 3: Aplikasi asli yang menggunakan komponen COM yang dibuat dengan versi .NET Framework yang lebih lama yang ingin Anda jalankan dengan .NET Framework 4.

    Versi .NET Framework yang diinstal: .NET Framework 4.

    Apa yang harus dilakukan: Dalam file konfigurasi aplikasi di direktori aplikasi, gunakan elemen <startup> dengan atribut useLegacyV2RuntimeActivationPolicy diatur ke true dan elemen <supportedRuntime> diatur sebagai berikut:

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

Contoh

Contoh berikut menunjukkan host COM tidak terkelola yang menjalankan komponen COM terkelola dengan menggunakan versi .NET Framework yang komponennya dikompilasi untuk digunakan.

Untuk menjalankan contoh berikut, kompilasi dan daftarkan komponen COM terkelola berikut menggunakan .NET Framework 3.5. Untuk mendaftarkan komponen, pada menu Proyek, klik Properti, klik tab Build, lalu pilih kotak centang Daftar untuk interop 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);
        }
    }
}

Kompilasikan aplikasi C++ tidak terkelola berikut ini, yang mengaktifkan objek COM yang dibuat oleh contoh sebelumnya.

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

Lihat juga