Pogledajte ostale proizvode na koje se ovaj članak odnosi.
Simptomi
Kada aplikaciju sustava Microsoft Office automatizirate iz programa Microsoft Visual Basic .NET ili Microsoft Visual C# .NET, aplikacija sustava Office ne zatvara se kada pozovete metodu zatvaranja.
Uzrok
Kada Visual Studio .NET pozove COM objekt iz upravljanog koda, on automatski stvara Runtime Callable Wrapper (RCW). RCW raspoređuje pozive između aplikacije .NET i objekta COM. RCW čuva broj referenci na COM objektu. Stoga, ako sve reference nisu objavljene na RCW-u, COM objekt neće zatvoriti.
Rješenje
Da biste bili sigurni da će aplikacija sustava Office zatvoriti, odredite ispunjava li vaš kod automatizacije sljedeće kriterije:
Deklarirajte svaki objekt kao novu varijablu. Promijenite, primjerice, sljedeći redak koda:
oBook = oExcel.Workbooks.Add()Promijenite to u sljedeće:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()Koristite System.Runtime.InteropServices.Marshal.ReleaseComObject u petlji sve dok ne vrati 0 nakon završetka korištenja objekta. Objekt System.Runtime.InteropServices.Marshal.ReleaseComObject smanjuje broj referenci RCW-a, a petlja osigurava da će se temeljna COM komponenta osloboditi bez obzira na to koliko je puta ponovno ušla u CLR.
Da biste oslobodili referencu na varijablu, postavite varijablu na Ništa ili Null.
Koristite metodu Quit objekta aplikacije sustava Office da biste poslužitelju rekli da se isključi.
Status
Takvo je ponašanje zadano.
Dodatne informacije
Koraci za reproduciranje ponašanja
Pokrenite Visual Studio .NET.
Na izborniku Datoteka kliknite Novo, a zatim Projiciranje. U odjeljku Projekti programa Visual Basic odaberite Aplikacija sustava Windows, a zatim kliknite U redu.
Napomena Obrazac1 se stvara prema zadanim postavkama.
Dodajte referencu u biblioteku objekata programa Microsoft Excel. Slijedite korake u nastavku.
On the Project menu, click Add Reference.
Na kartici COM pronađite biblioteku objekata programa Excel, a zatim kliknite Odaberi.
Za Microsoft Excel 2002: Biblioteka objekata programa Microsoft Excel 10.0
Napomena Ako to još niste učinili, preporučujemo da preuzmete i instalirate primarne međuoperativne sklopove (PIA) sustava Microsoft Office XP.
Dodatne informacije o PIA-ama za Office XP potražite u sljedećem članku iz Microsoftove baze znanja:
328912 Primarni skupovi međuoperacije (PIA) sustava Microsoft Office XP dostupni su za preuzimanje
Za Microsoft Office Excel 2003: Biblioteka objekata programa Microsoft Excel 11.0Kliknite U redu u dijaloškom okviru Dodavanje referenci da biste prihvatili odabir.
Na izborniku Prikaz kliknite Alatni okvir, a zatim povucite kontrolu gumba na Obrazac1.
Gumb za dvoklik1.
Napomena Prikazat će se prozor koda za obrazac.
Dodajte sljedeći kod na vrh Form1.vb:
Imports Microsoft.Office.InteropU prozoru koda zamijenite sljedeći kod:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click End SubZamijenite sljedeći 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 SubPritisnite F5 da biste pokrenuli aplikaciju.
Otvorite upravitelj zadataka sustava Windows. U programu Visual Studio prikažite prozor Izlaz da biste vidjeli poruke o ispravljanju pogrešaka. Kliknite naredbeni gumb. Primijetite da se instanca Excel.exe pojavljuje na popisu Procesi.
Instanca programa Excel i dalje se izvodi na popisu zadataka čak i kada aplikacija završi s radom u stanju mirovanja. Zatvorite dijaloški okvir i primijetite da se Excel više ne pojavljuje na popisu Procesi.
Kada prođete korake u odjeljku "Razlučivost", aplikacija sustava Office zatvorit će se nakon što otpusti zadnju varijablu. Zamijenite funkciju u 5. koraku pomoću sljedećeg koda:
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
Ako koristite Visual C# .NET, referencirajte kod za funkciju NAR():
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch {}
finally
{
o = null;
}
}
Napomena Počevši od verzije .NET Framework 2.0, možete koristiti System.Runtime.InteropServices.Marshal.FinalReleaseComObject umjesto petlje while koja poziva System.Runtime.InteropServices.Marshal.ReleaseComObject kako biste postigli isti rezultat.
Otklanjanje poteškoća
Napomena Ako slijedite korake opisane u odjeljku "Koraci za reproduciranje ponašanja", a poslužitelj se i dalje ne isključuje, možete koristiti GC. Collect() i GC. WaitForPendingFinalizers() nakon puštanja zadnjeg objekta. Budući da okruženje izvršavanje obavlja prikupljanje smeća na RCW-u, GC. Metoda Collect() prisiljava sakupljač smeća da se pokrene i može osloboditi sve reference koje RCW još ima. The GC. Metoda Collect() pokušava vratiti maksimalnu dostupnu memoriju. Obratite pozornost na to da to ne jamči da će se vratiti sva memorija.
Odnosi se na
Ovaj se članak odnosi i na:
- Microsoft Visual Basic .NET (sva izdanja)
- Microsoft Visual C# .NET (sva izdanja)
- Microsoft Office 2016 (sva izdanja)
- Microsoft Office 2013 (sva izdanja)