Consultați celelalte produse la care se aplică acest articol.
Simptome
Atunci când automatizați o aplicație Microsoft Office din Microsoft Visual Basic .NET sau Microsoft Visual C# .NET, aplicația Office nu se închide atunci când apelați metoda Ieșire.
Cauză
Atunci Visual Studio .NET apelează un obiect COM din codul gestionat, acesta creează automat un Runtime Callable Wrapper (RCW). RcW locuează apeluri între aplicația .NET și obiectul COM. RCW păstrează un contor de referințe pe obiectul COM. Prin urmare, dacă nu au fost lansate toate referințele în RCW, obiectul COM nu se închide.
Rezolvare
Pentru a vă asigura că Office aplicației se închide, determinați dacă codul de automatizare îndeplinește următoarele criterii:
-
Declarați fiecare obiect ca o variabilă nouă. De exemplu, modificați următoarea linie de cod:
oBook = oExcel.Workbooks.Add()
Modificați următoarele:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()
-
Utilizați System.Runtime.InteropServices.În buclă.ReleaseComObject în buclă până când returnează 0 după ce ați terminat de utilizat un obiect. System.Runtime.InteropServices.ReleaseComObject decrementează numărul de referințe AL RCW și bucla se asigură că este lansată componenta COM subiacentă, indiferent de câte ori a intrat din nou în CLR.
-
Pentru a elibera referința la variabilă, setați variabila la valoarea Nimic sau Nul.
-
Utilizați metoda Închidere a obiectului Office pentru a spune serverului să închidă.
Stare
Acest comportament este implicit.
Mai multe informații
Steps to reproduce the behavior
-
Porniți Visual Studio .NET.
-
În meniul Fișier, faceți clic pe Nou, apoi faceți clic pe Project. Sub Visual Basic proiect, selectați Windows, apoi faceți clic pe OK.
Notă Formularul1 este creat în mod implicit. -
Adăugați o referință la Biblioteca Microsoft Excel obiecte. Pentru a face acest lucru, urmați acești pași:
-
În meniul de Project, faceți clic pe Adăugare referință.
-
Pe fila COM, găsiți Bibliotecă de obiecte pentru Excel, apoi faceți clic pe Selectare.
Pentru Microsoft Excel 2002: Microsoft Excel 10.0 Object LibraryNote Dacă nu ați făcut deja acest lucru, vă recomandăm să descărcați și să instalați Microsoft Office XP Primary Interop Assemblies (PIAS). Pentru mai multe informații despre Office PIAS XP, accesați următorul articol din Baza de cunoștințe Microsoft:328912 Microsoft Office asamblări (PIA) principale XP sunt disponibile pentru descărcare Pentru Microsoft Office Excel 2003: Microsoft Excel de obiecte 11.0
-
Faceți clic pe OK în caseta de dialog Adăugare referințe pentru a accepta selecțiile.
-
-
În meniul Vizualizare, faceți clic pe Casetă de instrumente, apoi glisați un control Buton în Formular1.
-
Faceți dublu clic pe Buton1.
Notă Apare fereastra de cod pentru formular. -
Adăugați următorul cod în partea de sus a Form1.vb:
Imports Microsoft.Office.Interop
-
Înlocuiți următorul cod în fereastra codului:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click End Sub
Înlocuiți următorul cod:
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 Sub
-
Apăsați F5 pentru a rula aplicația.
-
Deschideți Windows de activități. În Visual Studio, afișați fereastra Rezultat pentru a vedea mesajele de depanare. Faceți clic pe butonul de comandă. Observați că o instanță de Excel.exe apare în lista Procese.
-
Instanța de Excel încă rulează în lista de activități, chiar și după ce aplicația s-a terminat de adormit. Închideți caseta de dialog și observați Excel mai apare în lista Procese.
-
Când urmați pașii din secțiunea "Rezoluție", aplicația Office iese după ce eliberează ultima variabilă. Înlocuiți funcția din Pasul 5, utilizând următorul cod:
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
Dacă utilizați Visual C# .NET, faceți referire la codul pentru funcția NAR():
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch {}
finally
{
o = null;
}
}
Notă Începând cu .NET Framework 2.0, puteți utiliza System.Runtime.InteropServices.În locul rezumatuluiComObject în locul apelării în buclă System.Runtime.InteropServices.Serif.ReleaseComObject pentru a obține același rezultat.
Depanarea problemelor
Notă Dacă urmați pașii descriți în secțiunea "Pașii de reproducere a comportamentului", iar serverul tot nu se închide, puteți utiliza GC. Metoda Colectare() și GC. Metoda WaitForPending Cevalizers() după ce eliberați ultimul obiect. Deoarece timpul de rulare execută coșul de gunoi de la RCW, GC. Metoda Collect() forțează coșul de gunoi să ruleze și poate lansa orice referințe pe care RCW le are încă. Este GC. Metoda Collect() încearcă să revendice memoria maximă disponibilă. Observați că acest lucru nu garantează că va fi recuperată toată memoria.
Se aplică la
Acest articol se aplică și la:
-
Microsoft Visual Basic .NET (toate edițiile)
-
Microsoft Visual C# .NET (toate edițiile)
-
Microsoft Office 2016 (toate edițiile)
-
Microsoft Office 2013 (toate edițiile)