Se de andre produkter, som denne artikel gælder for.
Symptomer
Når du automatiserer et Microsoft Office-program fra Microsoft Visual Basic .NET eller Microsoft Visual C# .NET, afsluttes Office-programmet ikke, når du kalder metoden Afslut.
Årsag
Når Visual Studio .NET kalder et COM-objekt fra administreret kode, opretter det automatisk en Runtime Callable Wrapper (RCW). RCW overvåger kald mellem .NET-programmet og COM-objektet. RCW holder et referenceantal for COM-objektet. Så hvis alle referencer ikke er blevet frigivet på RCW, afsluttes COM-objektet ikke.
Løsning
For at sikre, at Office-programmet afsluttes, skal du afgøre, om din automatiseringskode opfylder følgende kriterier:
Definer hvert objekt som en ny variabel. Du kan f.eks. ændre følgende kodelinje:
oBook = oExcel.Workbooks.Add()Skift dette til følgende:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()Brug System.Runtime.InteropServices.Marshal.ReleaseComObject i en løkke, indtil 0 returneres, når du er færdig med at bruge et objekt. System.Runtime.InteropServices.Marshal.ReleaseComObject reducerer referenceantallet for RCW'en, og løkken sikrer, at den underliggende COM-komponent frigives, uanset hvor mange gange den er genindsat i CLR.
Hvis du vil frigive referencen til variablen, skal du sætte variablen til lig med Nothing eller Null.
Brug metoden Afslut i Office-programobjektet til at bede serveren om at lukke ned.
Status
Denne funktionsmåde er tilsigtet.
Flere oplysninger
Trin til genskabelse af problemet
Start Visual Studio .NET.
Klik på Ny i menuen Filer, og klik derefter på Projekt. Vælg Windows-program under Visual Basic-projekter, og klik derefter på OK.
Bemærk Formular1 oprettes som standard.
Føj en reference til Microsoft Excel-objektbiblioteket. Det kan du gøre ved at udføre disse trin:
Klik på Tilføj reference i menuen Projekter.
Find objektbiblioteket til Excel under fanen COM, og klik derefter på Markér.
Til Microsoft Excel 2002: Microsoft Excel 10.0-objektbibliotek
Bemærk Hvis du ikke allerede har gjort det, anbefaler vi, at du henter og installerer Microsoft Office XP Primary Interop Assemblies (PIA'er).
Du kan finde flere oplysninger om Office XP PIA'er i følgende artikel i Microsoft Knowledge Base:
328912 Primære interop-samlinger (PIA'er) i Microsoft Office XP kan downloades
Microsoft Office Excel 2003: Microsoft Excel 11.0-objektbibliotekKlik på OK i dialogboksen Tilføj referencer for at acceptere dine valg.
Klik på Værktøjskasse i menuen Vis, og træk derefter en knap til Formular1.
Dobbeltklik på knap1.
Bemærk Kodevinduet for formularen vises.
Føj følgende kode til toppen af Form1.vb:
Imports Microsoft.Office.InteropUdskift følgende kode i kodevinduet:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click End SubErstat med følgende kode:
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 SubTryk på F5 for at køre programmet.
Åbn Windows Jobliste. I Visual Studio skal du vise vinduet Output for at få vist fejlfindingsmeddelelserne. Klik på kommandoknappen. Bemærk, at der vises en forekomst af Excel.exe på listen Processer.
Excel-forekomsten kører stadig på opgavelisten, også efter programmet er færdigt med at slumre. Luk dialogboksen, og bemærk, at Excel ikke længere vises på listen over processer.
Når du følger trinnene i afsnittet "Løsning", afsluttes Office-programmet, efter at den sidste variabel er udgivet. Erstat funktionen i trin 5 ved hjælp af følgende kode:
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
Hvis du bruger Visual C# .NET, skal du referere til koden for funktionen NAR():
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch {}
finally
{
o = null;
}
}
Bemærk: Fra og med .NET Framework 2.0 kan du bruge System.Runtime.InteropServices.Marshal.FinalReleaseComObject i stedet for while-løkken, der kalder System.Runtime.InteropServices.Marshal.ReleaseComObject for at opnå det samme resultat.
Fejlfinding
Bemærk Hvis du følger de trin, der er beskrevet i afsnittet "Trin til at genskabe funktionsmåden", og serveren stadig ikke lukker, kan du bruge GC. Collect()-metoden og GC. WaitForPendingFinalizers()-metoden, når du har sluppet det sidste objekt. Da runtime udfører affaldsindsamling på RCW, GC. Collect()-metoden tvinger garbage collector til at køre og kan frigive eventuelle referencer, som RCW'en stadig har. The GC. Collect()-metoden forsøger at frigøre den maksimale hukommelse, der er tilgængelig. Bemærk, at dette ikke garanterer, at al hukommelse vil blive frigjort.
Gælder for
Denne artikel gælder også for:
- Microsoft Visual Basic .NET (alle udgaver)
- Microsoft Visual C# .NET (alle udgaver)
- Microsoft Office 2016 (alle udgaver)
- Microsoft Office 2013 (alle udgaver)