Symptomy
W przypadku automatyzacji Microsoft Office z programu Microsoft Visual Basic .NET lub Microsoft Visual C# .NET aplikacja Office nie zamyka się po wywołaniu metody Quit.
Przyczyna
Gdy Visual Studio .NET wywołuje obiekt COM z kodu zarządzanego, automatycznie tworzy opakowanie w środowisku uruchomieniowym (RCW, Runtime Callable Wrapper). RcW marshals calls between the .NET application and the COM object. RcW zachowuje liczbę odwoływać się do obiektu COM. Dlatego, jeśli wszystkie odwołania nie zostały opublikowane w rcw, obiekt COM nie zostanie zamknięty.
Rozwiązanie
Aby mieć pewność, że Office zakończy działanie aplikacji, należy określić, czy kod automatyzacji spełnia następujące kryteria:
-
Zadeklaruj każdy obiekt jako nową zmienną. Na przykład zmień następujący wiersz kodu:
oBook = oExcel.Workbooks.Add()
Zmień to na następujące:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()
-
Użyj funkcji System.Runtime.InteropServices.Marshal.ReleaseComObject w pętli, aż po zakończeniu używania obiektu zwróci ona wartość 0. System.Runtime.InteropServices.Marshal.ReleaseComObject zmniejsza liczbę odwoływać się do pliku RCW, a pętla zapewnia, że źródłowy składnik COM zostanie wydany niezależnie od tego, ile razy ponownie wprowadzono składnik CLR.
-
Aby zwolnić odwołanie do zmiennej, ustaw zmienną równą Nic lub Null.
-
Użyj metody Quit obiektu Office, aby powiedzieć serwerowi o zamknięciu.
Stan
Takie działanie jest celowe.
Więcej informacji
Czynności, które należy wykonać w celu odtworzenia zachowania
-
Uruchom Visual Studio .NET.
-
W menu Plik kliknij pozycję Nowy, a następnie kliknij pozycję Project. W Visual Basic projektów wybierz pozycję Windows aplikacji, a następnie kliknij przycisk OK.
Uwaga Domyślnie jest tworzony formularz 1. -
Dodaj odwołanie do biblioteki Microsoft Excel obiektów. W tym celu wykonaj następujące czynności:
-
W menu Projekt kliknij polecenie Dodaj odwołanie.
-
Na karcie COM znajdź pozycję Biblioteka obiektów dla Excel, a następnie kliknij przycisk Wybierz.
W przypadku programu Microsoft Excel 2002: Microsoft Excel 10.0 Object LibraryNote Jeśli jeszcze tego nie zrobiono, zalecamy pobranie i zainstalowanie podstawowych zestawów międzysieciowych Microsoft Office XP. Aby uzyskać więcej informacji na Office XP PIA, przejdź do następującego artykułu z bazy wiedzy Microsoft Knowledge Base:328912 Microsoft Office xp podstawowych zestawów międzyplatplatowych (PIA) są dostępne do pobrania Dla Microsoft Office Excel 2003: Microsoft Excel 11.0 Object Library
-
Kliknij przycisk OK w oknie dialogowym Dodawanie odwołań, aby zaakceptować wybrane opcje.
-
-
W menu Widok kliknij polecenie Zestaw narzędzi, a następnie przeciągnij kontrolkę Przycisk do formularza Form1.
-
Kliknij dwukrotnie przycisk1.
Uwaga Zostanie wyświetlone okno kodu formularza. -
Dodaj następujący kod u góry strony Form1.vb:
Imports Microsoft.Office.Interop
-
Zamień następujący kod w oknie kodu:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click End Sub
Podstawiaj następujący kod:
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
-
Naciśnij klawisz F5, aby uruchomić aplikację.
-
Otwieranie Windows zadań. W Visual Studio wyświetl okno Dane wyjściowe, aby wyświetlić komunikaty debugowania. Kliknij przycisk polecenia. Zwróć uwagę, że wystąpienie Excel.exe się na liście Procesy.
-
Wystąpienie programu Excel nadal działa na liście zadań nawet po zakończeniu uśpienia aplikacji. Zamknij okno dialogowe i zwróć uwagę, że Excel nie jest już wyświetlany na liście Procesy.
-
Po zakończeniu czynności w sekcji "Rozdzielczość" aplikacja Office zamyka się po zwolnieniu ostatniej zmiennej. Zastąp funkcję w kroku 5 następującym kodem:
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
Jeśli używasz języka Visual C# .NET, odwołuj się do kodu funkcji NAR():
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch {}
finally
{
o = null;
}
}
Uwaga Od wersji .NET Framework 2.0 możesz użyć funkcji System.Runtime.InteropServices.Marshal.FinalReleaseComObject zamiast połączeń w pętli System.Runtime.InteropServices.Marshal.ReleaseComObject, aby osiągnąć taki sam wynik.
Rozwiązywanie problemów
Uwaga 16. Jeśli posuniesz czynności opisane w sekcji "Procedura odtworzenia zachowania", a serwer nadal nie zostanie zamknięty, możesz użyć funkcji NAJW. Metoda Collect() i NAJW. Metoda WaitForPendingFinalizers() po zwolnieniu ostatniego obiektu. Ponieważ środowisko uruchomieniowe wykonuje kolekcję koszy w rcw, najww. Metoda Collect() wymusza uruchomienie kosza na śmieci i może spowodować zwolnienie wszelkich odwołań, które nadal ma WKW. NAJW. Metoda Collect() próbuje odzyskać maksymalną dostępną pamięć. Zwróć uwagę, że nie gwarantuje to, że odzyskamy całą pamięć.
Informacje zawarte w tym artykule dotyczą
Ten artykuł dotyczy również:
-
Microsoft Visual Basic .NET (wszystkie wersje)
-
Microsoft Visual C# .NET (wszystkie wersje)
-
Microsoft Office 2016 (wszystkie wersje)
-
Microsoft Office 2013 (wszystkie wersje)