Panduan untuk Menerapkan Ekstensi In-Process
Ekstensi dalam-proses dimuat ke dalam proses apa pun yang memicu ekstensi tersebut. 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, perhatian harus diberikan agar tidak berdampak negatif pada aplikasi host atau ekstensi dalam proses lainnya.
Satu runtime yang patut diperhatikan adalah common language runtime (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 untuk direproduksi karena kegagalan memerlukan ekstensi yang bertentangan dan mode kegagalan yang tepat 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 file Open berpotensi untuk memuat kode terkelola dialog dan dependensi CLR terkait ke dalam proses aplikasi tersebut. 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 Open dibangun pada versi CLR yang bertentangan, maka 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 secara acak berhenti berfungsi, 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 hidup berdampingan satu sama lain dan dengan sebagian besar versi clr pra-4.0 (dengan pengecualian versi 1.0, yang tidak dapat hidup berdampingan dengan versi lain). Namun, masalah selain konflik versi dapat muncul seperti yang dibahas di sisa topik ini.
Masalah Performa
Masalah performa dapat muncul pada runtime yang mengalami penurunan performa signifikan saat dimuat ke dalam proses. Penalti performa dapat berupa penggunaan memori, penggunaan CPU, waktu yang terpakai, atau bahkan penggunaan 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 yang signifikan dapat menyebabkan kegagalan pada proses host atau ekstensi lain yang dalam proses. Misalnya, waktu proses yang berdampak besar pada kinerja dan mengonsumsi ratusan megabyte ruang alamat memori untuk memori heap-nya 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, maka 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. Ini bukan daftar lengkap dari semua kemungkinan masalah yang mungkin Anda temui. Masalah yang dibahas di sini adalah kedua alasan kode terkelola tidak didukung dalam ekstensi dan poin yang perlu dipertimbangkan saat Anda mengevaluasi penggunaan runtime lain.
Re-entri
Ketika CLR memblokir utas apartemen berulir tunggal (STA), misalnya, karena Monitor.Enter, WaitHandle.WaitOne, atau pernyataan kunci, 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 dihancurkan kemudian oleh finalizer CLR, yang merupakan bagian dari MTA (kompartemen multithreaded). Memindahkan proksi dari STA ke MTA memerlukan pemrosesan marshalling, tetapi tidak semua antarmuka yang digunakan oleh ekstensi dapat diproses dengan cara ini.
Masa Hidup Objek Non-Deterministik
CLR memiliki jaminan masa pakai 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 kantong properti yang dipertahankan oleh objek ketika metode Load mengembalikan.
- Jika referensi objek CLR dikembalikan ke kode asli, Runtime Callable Wrapper melepaskan referensinya ke objek CLR ketika panggilan akhir Runtime Callable Wrapper ke Release dibuat, tetapi objek CLR yang mendasarinya tidak diselesaikan sampai dikumpulkan sampah. Finalisasi nondeterministik dapat bertentangan dengan beberapa kontrak antarmuka. Misalnya, handler gambar mini diperlukan untuk segera merilis semua sumber daya ketika jumlah referensinya turun ke nol.
Penggunaan Kode Terkelola dan Runtime Lainnya yang Dapat Diterima
Dapat diterima untuk menggunakan kode terkelola dan runtime lain untuk menerapkan ekstensi di luar proses. Contoh ekstensi Shell di luar proses meliputi yang berikut ini:
- Penangan pratinjau
- Tindakan berbasis baris perintah seperti yang terdaftar di bawah shell\kata aksi\perintah subkunci.
- 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 terkait dengan entri DelegateExecute yang terdaftar di bawah shell\kata kerja\perintah subkunci.
- IDropTarget yang terkait dengan CLSID yang terdaftar di bawah shell\kata kerja\DropTarget subkey.
- IExplorerCommandState yang terkait dengan entri CommandStateHandler yang terdaftar di bawah shell\kata kerja subkunci.