Lihat produk lain yang berlaku untuk artikel ini.
Gejala
Saat Anda mengotomatisasi aplikasi Microsoft Office dari Microsoft Visual Basic .NET atau Microsoft Visual C# .NET, aplikasi Office tidak keluar saat Anda memanggil metode Keluar.
Penyebab
Ketika Visual Studio .NET memanggil objek COM dari kode terkelola, secara otomatis membuat Runtime Callable Wrapper (RCW). RCW marshals panggilan antara aplikasi .NET dan objek COM. RCW menyimpan hitungan referensi pada objek COM. Oleh karena itu, jika semua referensi belum dirilis di RCW, objek COM tidak berhenti.
Resolusi
Untuk memastikan bahwa aplikasi Office keluar, tentukan apakah kode otomatisasi Anda memenuhi kriteria berikut:
Mendeklarasikan setiap objek sebagai variabel baru. Misalnya, ubah baris kode berikut ini:
oBook = oExcel.Workbooks.Add()Ubah ini ke hal berikut ini:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()Gunakan System.Runtime.InteropServices.Marshal.ReleaseComObject dalam pengulangan hingga mengembalikan 0 setelah selesai menggunakan objek. System.Runtime.InteropServices.Marshal.ReleaseComObject menentukan hitungan referensi RCW, dan pengulangan memastikan bahwa komponen COM yang mendasarinya dirilis terlepas dari berapa kali komponen tersebut telah masuk kembali ke CLR.
Untuk melepaskan referensi ke variabel, atur variabel sama dengan Tidak Ada atau Null.
Gunakan metode Keluar dari objek aplikasi Office untuk memberi tahu server untuk mematikan.
Status
Perilaku ini memang direncanakan.
Informasi Selengkapnya
Langkah-langkah untuk mereprodusi perilaku
Mulai Visual Studio .NET.
Pada menu File, klik Baru, lalu klik Proyek. Di bawah Proyek Visual Basic, pilih Aplikasi Windows, lalu klik OK.
Catatan Formulir1 dibuat secara default.
Tambahkan referensi ke Pustaka Objek Microsoft Excel. Untuk melakukannya, ikuti langkah-langkah berikut:
Pada menu Proyek, klik Tambahkan Referensi.
Pada tab COM, temukan Pustaka Objek untuk Excel, lalu klik Pilih.
Untuk Microsoft Excel 2002: Pustaka Objek Microsoft Excel 10.0
Catatan Jika Anda belum melakukan ini, kami menyarankan agar Anda mengunduh dan menginstal Microsoft Office XP Primary Interop Assemblies (PIAS).
Untuk informasi selengkapnya tentang Office XP PIAS, masuk ke artikel Pangkalan Pengetahuan Microsoft berikut ini:
328912 Microsoft Office XP primary interop assemblies (PIAS) tersedia untuk diunduh
Untuk Microsoft Office Excel 2003: Pustaka Objek Microsoft Excel 11.0Klik OK dalam kotak dialog Tambahkan Referensi untuk menerima pilihan Anda.
Pada menu Tampilan, klik Kotak Alat, lalu seret kontrol Tombol ke Formulir1.
Klik ganda Tombol1.
Catatan Jendela kode untuk formulir akan muncul.
Tambahkan kode berikut ke bagian atas Form1.vb:
Imports Microsoft.Office.InteropGanti kode berikut di jendela kode:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click End SubGanti kode berikut:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim oApp As New Excel.Application() Dim oBook As Excel.Workbook = oApp.Workbooks.Add Dim oSheet As Excel.Worksheet = oApp.ActiveSheet oSheet = Nothing oBook.Close(False) oBook = Nothing oApp.Quit() oApp = Nothing Debug.WriteLine("Sleeping...") System.Threading.Thread.Sleep(5000) Debug.WriteLine("End Excel") End SubTekan F5 untuk menjalankan aplikasi.
Buka Manajer Tugas Windows. Di Visual Studio, tampilkan jendela Output untuk melihat pesan debug. Klik tombol perintah. Perhatikan bahwa contoh Excel.exe muncul dalam daftar Proses.
Contoh Excel masih berjalan dalam daftar tugas bahkan setelah aplikasi selesai tidur. Tutup kotak dialog dan perhatikan bahwa Excel tidak lagi muncul dalam daftar Proses.
Saat Anda melakukan langkah-langkah di bagian "Resolusi", aplikasi Office keluar setelah merilis variabel terakhir. Ganti fungsi di Langkah 5 dengan menggunakan kode berikut:
Private Sub NAR(ByVal o As Object) Try While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) End While Catch Finally o = Nothing End Try End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim oApp As New Excel.Application() Dim oBooks As Excel.Workbooks = oApp.Workbooks Dim oBook As Excel.Workbook = oBooks.Add Dim oSheet As Excel.Worksheet = oApp.ActiveSheet NAR(oSheet) oBook.Close(False) NAR(oBook) NAR(oBooks) oApp.Quit() NAR(oApp) Debug.WriteLine("Sleeping...") System.Threading.Thread.Sleep(5000) Debug.WriteLine("End Excel") End Sub
Jika Anda menggunakan Visual C# .NET, referensikan kode untuk fungsi NAR():
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch {}
finally
{
o = null;
}
}
Catatan Dimulai dari .NET Framework 2.0, Anda dapat menggunakan System.Runtime.InteropServices.Marshal.FinalReleaseComObject, bukan mengulang panggilan System.Runtime.InteropServices.Marshal.ReleaseComObject untuk mendapatkan hasil yang sama.
Pemecahan masalah
Catatan Jika Anda mengikuti langkah-langkah yang dijelaskan di bagian "Langkah-langkah untuk Mereproduksi Perilaku", dan server masih tidak dimatikan, Anda bisa menggunakan GC. Metode Collect() dan GC. Metode WaitForPendingFinalizers() setelah Anda melepaskan objek terakhir. Karena runtime melakukan pengumpulan sampah di RCW, GC. Metode Collect() memaksa kolektor sampah untuk berjalan dan mungkin merilis referensi apa pun yang masih dimiliki RCW. The GC. Metode Collect() mencoba mengambil kembali memori maksimum yang tersedia. Perhatikan bahwa ini tidak menjamin bahwa semua memori akan diklaim kembali.
Berlaku untuk
Artikel ini juga berlaku untuk:
- Microsoft Visual Basic .NET (semua edisi)
- Microsoft Visual C# .NET (semua edisi)
- Microsoft Office 2016 (semua edisi)
- Microsoft Office 2013 (semua edisi)