Lesen Sie die anderen Produkte, für die dieser Artikel gilt.
Problembeschreibung
Wenn Sie eine Microsoft Office-Anwendung aus Microsoft Visual Basic .NET oder Microsoft Visual C# .NET automatisieren, wird die Office-Anwendung beim Aufrufen der Beenden-Methode nicht beendet.
Ursache
Wenn Visual Studio .NET ein COM-Objekt aus verwalteten Code aufruft, erstellt es automatisch einen aufrufbaren Runtime Wrapper (RCW). Das RCW-Marshalling ruft zwischen der .NET-Anwendung und dem COM-Objekt auf. Die RCW behält die Verweisanzahl für das COM-Objekt bei. Wenn also nicht alle Verweise vom RCW freigegeben wurden, wird das COM-Objekt nicht beendet.
Lösung
Um sicherzustellen, dass die Office-Anwendung beendet wird, bestimmen Sie, ob Ihr Automatisierungscode die folgenden Kriterien erfüllt:
-
Deklarieren Sie jedes Objekt als neue Variable. Ändern Sie beispielsweise die folgende Codezeile:
oBook = oExcel.Workbooks.Add()
Ändern Sie dies in Folgendes:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()
-
Verwenden Sie System.Runtime.InteropServices.Marshal.ReleaseComObject in einer Schleife, bis 0 zurückgegeben wird, wenn Sie mit der Verwendung eines -Objekts fertig sind. Das System.Runtime.InteropServices.Marshal.ReleaseComObject-Element bestimmt die Verweisanzahl des RCW, und die Schleife stellt sicher, dass die zugrunde liegende COM-Komponente unabhängig davon freigegeben wird, wie oft sie erneut in die CLR eingegeben wurde.
-
Um den Verweis auf die Variable frei geben, legen Sie die Variable auf Nothing oder Null fest.
-
Verwenden Sie die "Quit"-Methode Office Anwendungsobjekt, um den Server zum Herunterfahren zu informieren.
Status
Es handelt sich hierbei um ein beabsichtigtes Verhalten.
Weitere Informationen
Schritte zum Reproduzieren des Verhaltens
-
Starten Visual Studio .NET.
-
Klicken Sie im Menü Datei auf Neu, und klicken Sie dann auf Project. Wählen Visual Basic unter Projekte die Option Windows aus, und klicken Sie dann auf OK.
Hinweis Formular1 wird standardmäßig erstellt. -
Fügen Sie einen Verweis auf die Microsoft Excel-Objektbibliothek hinzu. Gehen Sie zu diesem Zweck folgendermaßen vor:
-
Klicken Sie im Menü Projekt auf Verweis hinzufügen.
-
Suchen Sie auf der Registerkarte COM die Objektbibliothek für Excel, und klicken Sie dann auf Auswählen.
Für Microsoft Excel 2002: Microsoft Excel 10.0-Objektbibliotheksnotizen Wenn dies noch nicht geschehen ist, empfehlen wir, die primären Microsoft Office XP-Inopassemblys (PIAs) herunterzuladen und zu installieren. Weitere Informationen zu Office XP-PIAs finden Sie im folgenden Microsoft Knowledge Base-Artikel:328912 Microsoft Office FÜR XP stehen primäre INOP-Assemblys (PIAs) zum Download zur Verfügung. Für Microsoft Office Excel 2003: Microsoft Excel 11.0-Objektbibliothek
-
Klicken Sie im Dialogfeld Verweise hinzufügen auf OK, um Ihre Auswahl zu übernehmen.
-
-
Klicken Sie im Menü Ansicht auf Toolbox, und ziehen Sie dann ein Button-Steuerelement auf Form1.
-
Doppelklicken Sie auf Schaltfläche1.
Hinweis Das Codefenster für das Formular wird angezeigt. -
Fügen Sie oben in "Form1.vb" den folgenden Code hinzu:
Imports Microsoft.Office.Interop
-
Ersetzen Sie den folgenden Code im Codefenster:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click End Sub
Ersetzen Sie den folgenden Code:
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
-
Drücken Sie [F5], um die Anwendung auszuführen.
-
Öffnen Windows Task-Manager. Zeigen Visual Studio Ausgabefenster an, um die Debugmeldungen anzuzeigen. Klicken Sie auf die Befehlsschaltfläche. Beachten Sie, dass eine Instanz Excel.exe in der Liste Prozesse angezeigt wird.
-
Die Instanz des Excel wird auch dann noch in der Aufgabenliste ausgeführt, wenn die Anwendung nicht mehr damit fertig ist. Schließen Sie das Dialogfeld, und beachten Sie, Excel in der Liste Prozesse nicht mehr angezeigt wird.
-
Wenn Sie die Schritte im Abschnitt "Auflösung" ausführen, wird Office Anwendung beendet, nachdem die letzte Variable veröffentlicht wurde. Ersetzen Sie die Funktion in Schritt 5 mithilfe des folgenden Codes:
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
Wenn Sie Visual C# .NET verwenden, verweisen Sie auf den Code für die NAR()-Funktion:
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch {}
finally
{
o = null;
}
}
Hinweis Ab .NET Framework 2.0 können Sie System.Runtime.InteropServices.Marshal.FinalReleaseComObject anstelle der while-Schleife verwenden, die System.Runtime.InteropServices.Marshal.ReleaseComObject aufruft, um dasselbe Ergebnis zu erzielen.
Problembehandlung
Hinweis Wenn Sie die im Abschnitt "Schritte zum Reproduzieren des Verhaltens" beschriebenen Schritte ausführen und der Server trotzdem nicht heruntergefahren wird, können Sie die GG verwenden. Collect()-Methode und GG. WaitForPendingFinalizers()-Methode, nachdem Sie das letzte -Objekt freigegeben haben. Da die Laufzeit eine Garbage Collection für rcW, die GC, durchführt. Die Collect()-Methode zwingt die Ausführung des Garbage Collectors und gibt möglicherweise alle Verweise frei, die der RCW noch besitzt. The GC. Die Collect()-Methode versucht, den verfügbaren maximalen Arbeitsspeicher freigefordert zu haben. Beachten Sie, dass dadurch nicht garantiert wird, dass der ganze Arbeitsspeicher freigegeben wird.
Die Informationen in diesem Artikel beziehen sich auf
Dieser Artikel bezieht sich auch auf:
-
Microsoft Visual Basic .NET (alle Editionen)
-
Microsoft Visual C# .NET (alle Editionen)
-
Microsoft Office 2016 (alle Editionen)
-
Microsoft Office 2013 (alle Editionen)