Panduan untuk Menerapkan Ekstensi In-Process

Ekstensi dalam proses dimuat ke dalam proses apa pun yang memicunya. Misalnya, ekstensi namespace Shell dapat dimuat ke dalam proses apa pun yang mengakses namespace Shell baik secara langsung maupun tidak langsung. Namespace Shell digunakan oleh banyak operasi Shell, seperti tampilan dialog file umum, peluncuran dokumen melalui aplikasi terkait, atau perolehan ikon yang digunakan untuk mewakili file. Karena ekstensi dalam proses dapat dimuat ke dalam proses arbitrer, perawatan harus diambil agar tidak berdampak negatif pada aplikasi host atau ekstensi dalam proses lainnya.

Salah satu runtime catatan tertentu adalah runtime bahasa umum (CLR), juga dikenal sebagai kode terkelola atau .NET Framework. Microsoft merekomendasikan untuk tidak menulis ekstensi dalam proses terkelola ke Windows Explorer atau Windows Internet Explorer dan tidak menganggapnya sebagai skenario yang didukung.

Topik ini membahas faktor-faktor yang perlu dipertimbangkan ketika Anda menentukan apakah ada runtime selain CLR yang cocok untuk digunakan oleh ekstensi dalam proses. Contoh runtime lain termasuk Java, Visual Basic, JavaScript/ECMAScript, Delphi, dan pustaka runtime C/C++. Topik ini juga memberikan beberapa alasan bahwa kode terkelola tidak didukung dalam ekstensi dalam proses.

Konflik Versi

Konflik versi dapat muncul melalui runtime yang tidak mendukung pemuatan beberapa versi runtime dalam satu proses. Versi CLR sebelum versi 4.0 termasuk dalam kategori ini. Jika pemuatan satu versi runtime menghalangi pemuatan versi lain dari runtime yang sama, ini dapat membuat konflik jika aplikasi host atau ekstensi dalam proses lainnya menggunakan versi yang bertentangan. Dalam kasus konflik versi dengan ekstensi dalam proses lain, konflik mungkin sulit direproduksi karena kegagalan memerlukan ekstensi yang bertentangan yang tepat dan mode kegagalan tergantung pada urutan di mana ekstensi yang bertentangan dimuat.

Pertimbangkan ekstensi dalam proses yang ditulis menggunakan versi CLR sebelum versi 4.0. Setiap aplikasi di komputer yang menggunakan kotak dialog Buka file berpotensi memiliki kode terkelola dialog dan dependensi CLR penjawabnya yang dimuat ke dalam proses aplikasi. Aplikasi atau ekstensi yang pertama kali memuat clr versi pra-4.0 ke dalam proses aplikasi membatasi versi CLR mana yang dapat digunakan kemudian oleh proses tersebut. Jika aplikasi terkelola dengan kotak dialog Buka dibangun pada versi CLR yang bertentangan, ekstensi dapat gagal berjalan dengan benar dan dapat menyebabkan kegagalan dalam aplikasi. Sebaliknya, jika ekstensi adalah yang pertama dimuat dalam proses dan versi kode terkelola yang bertentangan mencoba diluncurkan setelah itu (mungkin aplikasi terkelola atau aplikasi yang sedang berjalan memuat CLR sesuai permintaan), operasi gagal. Bagi pengguna, tampaknya beberapa fitur aplikasi berhenti berfungsi secara acak, atau aplikasi secara misterius mengalami crash.

Perhatikan bahwa versi CLR sama dengan atau lebih baru dari versi 4.0 umumnya tidak rentan terhadap masalah penerapan versi karena dirancang untuk berdampingan satu sama lain dan dengan sebagian besar versi pra-4.0 CLR (dengan pengecualian versi 1.0, yang tidak dapat berdampingan dengan versi lain). Namun, masalah selain konflik versi dapat muncul seperti yang dibahas di sisa topik ini.

Masalah Performa

Masalah performa dapat muncul dengan runtime yang memberlakukan penalti performa yang signifikan saat dimuat ke dalam proses. Penalti performa dapat berupa penggunaan memori, penggunaan CPU, waktu yang berlalu, atau bahkan konsumsi ruang alamat. CLR, JavaScript/ECMAScript, dan Java dikenal sebagai runtime berdampak tinggi. Karena ekstensi dalam proses dapat dimuat ke dalam banyak proses, dan sering dilakukan pada saat-saat sensitif performa (seperti saat menyiapkan menu untuk ditampilkan pengguna), runtime berdampak tinggi dapat berdampak negatif pada responsivitas keseluruhan.

Runtime berdampak tinggi yang mengonsumsi sumber daya signifikan dapat menyebabkan kegagalan dalam proses host atau ekstensi dalam proses lainnya. Misalnya, runtime berdampak tinggi yang mengonsumsi ratusan megabyte ruang alamat untuk tumpukannya dapat mengakibatkan aplikasi host tidak dapat memuat himpunan data besar. Selain itu, karena ekstensi dalam proses dapat dimuat ke dalam beberapa proses, konsumsi sumber daya yang tinggi dalam satu ekstensi dapat dengan cepat dikalikan menjadi konsumsi sumber daya yang tinggi di seluruh sistem.

Jika runtime tetap dimuat atau terus menggunakan sumber daya bahkan ketika ekstensi yang menggunakan runtime tersebut telah dibongkar, runtime tersebut tidak cocok untuk digunakan dalam ekstensi.

Masalah Khusus untuk .NET Framework

Bagian berikut membahas contoh masalah yang ditemukan dengan menggunakan kode terkelola untuk ekstensi. Mereka bukan daftar lengkap dari semua kemungkinan masalah yang mungkin Anda temui. Masalah yang dibahas di sini adalah kedua alasan bahwa kode terkelola tidak didukung dalam ekstensi dan poin yang perlu dipertimbangkan ketika Anda mengevaluasi penggunaan runtime lain.

Re-entrancy

Ketika CLR memblokir utas apartemen berulir tunggal (STA), misalnya, karena monitor.Enter, WaitHandle.WaitOne, atau pernyataan kunci yang digabungkan, CLR, dalam konfigurasi standarnya, memasuki perulangan pesan berlapis saat menunggu. Banyak metode ekstensi dilarang memproses pesan, dan reentransi yang tidak dapat diprediksi dan tidak terduga ini dapat mengakibatkan perilaku anomali yang sulit untuk direproduksi dan didiagnosis.

Apartemen Multithreaded

CLR membuat Runtime Callable Wrappers untuk objek Model Objek Komponen (COM). Runtime Callable Wrappers yang sama ini dihancurkan kemudian oleh finalizer CLR, yang merupakan bagian dari apartemen multithreaded (MTA). Memindahkan proksi dari STA ke MTA memerlukan marshaling, tetapi tidak semua antarmuka yang digunakan oleh ekstensi dapat dinaungi.

Masa Pakai Objek Non-Deterministik

CLR memiliki jaminan seumur hidup objek yang lebih lemah daripada kode asli. Banyak ekstensi memiliki persyaratan jumlah referensi pada objek dan antarmuka, dan model pengumpulan sampah yang digunakan oleh CLR tidak dapat memenuhi persyaratan ini.

  • Jika objek CLR mendapatkan referensi ke objek COM, referensi objek COM yang dipegang oleh Runtime Callable Wrapper tidak dirilis sampai Runtime Callable Wrapper dikumpulkan sampah. Perilaku rilis nondeterministik dapat bertentangan dengan beberapa kontrak antarmuka. Misalnya, metode IPersistPropertyBag::Load mengharuskan tidak ada referensi ke tas properti yang dipertahankan oleh objek saat metode Muat kembali.
  • Jika referensi objek CLR dikembalikan ke kode asli, Runtime Callable Wrapper melepaskan referensinya ke objek CLR ketika panggilan akhir Runtime Callable Wrapper ke Rilis dilakukan, tetapi objek CLR yang mendasarinya tidak diselesaikan sampai dikumpulkan sampah. Finalisasi nondeterministik dapat bertentangan dengan beberapa kontrak antarmuka. Misalnya, penangan gambar mini diperlukan untuk segera merilis semua sumber daya ketika jumlah referensinya turun ke nol.

Penggunaan Kode Terkelola dan Runtime Lain yang Dapat Diterima

Dapat diterima untuk menggunakan kode terkelola dan runtime lain untuk menerapkan ekstensi di luar proses. Contoh ekstensi Shell yang tidak diproses meliputi yang berikut ini:

  • Penangan pratinjau
  • Tindakan berbasis baris perintah seperti yang terdaftar di bawah subkeyperintahkata kerja\shell\.
  • Objek COM yang diterapkan di server lokal, untuk titik ekstensi Shell yang memungkinkan aktivasi di luar proses.

Beberapa ekstensi dapat diimplementasikan baik sebagai ekstensi dalam proses atau di luar proses. Anda dapat menerapkan ekstensi ini sebagai ekstensi di luar proses jika tidak memenuhi persyaratan ini untuk ekstensi dalam proses. Daftar berikut menunjukkan contoh ekstensi yang dapat diimplementasikan sebagai ekstensi dalam proses atau di luar proses:

  • IExecuteCommand yang terkait dengan entri DelegateExecute yang terdaftar di bawah subkeyperintahkata kerja\shell\.
  • IDropTarget yang terkait dengan CLSID yang terdaftar di bawah katakerja\shell\DropTarget subkey.
  • IExplorerCommandState yang terkait dengan entri CommandStateHandler yang terdaftar di bawah subkuncikata kerjashell\.