Ознаки
Якщо автоматизувати програму Microsoft Office з Microsoft Visual Basic .NET або Microsoft Visual C#.NET, програма Office не завершуватиме роботу під час виклику методу Quit.
Причина
Коли Visual Studio .NET викликає об'єкт COM із керованого коду, він автоматично створює придатну до виконання програму Wrapper (RCW). Поля RCW лунає виклики між програмою .NET і об'єктом COM. Функція RCW зберігає кількість посилань для об'єкта COM. Таким чином, якщо не випущено всі посилання в RCW, об'єкт COM не закривається.
Спосіб вирішення
Щоб переконатися, що програма Office закривається, визначте, чи відповідає код автоматизації такі умови:
-
Оголосити кожний об'єкт як нову змінну. Наприклад, змініть такий рядок коду:
oBook = oExcel.Workbooks.Add()
Змініть цей параметр на такий:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()
-
Використовуйте system.Runtime.InteropServices.Marshal.ReleaseComObject у петлях, доки він не поверне 0, коли ви завершите використовувати об'єкт. Функція System.Runtime.InteropServices.Marshal.ReleaseComObject скрипить кількість посилань у функції RCW, а цикл забезпечує випуск базового компонента COM незалежно від того, скільки разів вона повторно ввела clR.
-
Щоб відпустити посилання на змінну, установіть для змінної значення Нічого або Null-значення.
-
Скористайтеся методом Quit об'єкта Office application, щоб повідомити серверу, що слід завершити роботу.
Стан
Це зроблено навмисно.
Додаткові відомості
Кроки для відтворення поведінки
-
Запустіть Visual Studio .NET.
-
У меню Файл виберіть команду Створити, а потім – Project. У Visual Basic Виберіть пункт Windows програма, а потім натисніть кнопку OK.
Примітка За замовчуванням створюється форма1. -
Додайте посилання на бібліотеку Microsoft Excel'єктів. Для цього зробіть ось що:
-
У меню Project клацніть Додати посилання.
-
На вкладці COM знайдіть бібліотеку об'єктів для Excel потім натисніть кнопку Вибрати.
У Microsoft Excel 2002: Microsoft Excel 10.0.
Бібліотека об'єктів Якщо ви цього ще не зробили, радимо завантажити та інсталювати основні вузли (PIAs) Microsoft Office XP.
Докладні відомості про Office PIAs див. в такій статті бази знань Microsoft:328912 Microsoft Office складання основних вузли (PIAs) XP, які можна завантажити
В Microsoft Office Excel 2003: Microsoft Excel 11.0. Бібліотека об'єктів -
Натисніть кнопку OK у діалоговому вікні Додавання посилань, щоб прийняти вибрані параметри.
-
-
У меню Вигляд клацніть Панель інструментів, а потім перетягніть елемент керування Кнопка на форму 1.
-
Двічі клацніть кнопку1.
Примітка Відкриється вікно коду форми. -
Додайте наведений нижче код у верхній частині Form1.vb:
Imports Microsoft.Office.Interop
-
Замініть наведений нижче код у вікні коду:
Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click 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 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
-
Натисніть клавішу F5, щоб запустити програму.
-
Відкрийте Windows Диспетчер завдань. У Visual Studio вікні "Вивід", щоб переглянути повідомлення про налагодження. Натисніть кнопку. Зверніть увагу, що екземпляр Excel.exe відображається в списку Процеси.
-
Екземпляр програми Excel завдання працювати в списку завдань навіть після того, як програма завершить режим сну. Закрийте діалогове вікно та зверніть увагу Excel що список процесів більше не відображається.
-
Якщо виконати кроки, описані в розділі "Вирішення", програма Office завершить її після випуску останньої змінної. Замініть функцію на кроці 5 таким кодом:
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
Якщо використовується Visual C# .NET, указівки на код функції NAR():
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch {}
finally
{
o = null;
}
}
Примітка. Починаючи з версії .NET Framework 2.0, можна використовувати system.Runtime.InteropServices.Marshal.FinalReleaseComObject, а не "loop calling System.Runtime.InteropServices.Marshal.ReleaseComObject", щоб отримати такий самий результат.
Виправлення неполадок
Примітка. Якщо виконати дії, описані в розділі "Кроки для відтворення поведінки", а сервер усе одно не вимкнуто, можна скористатися GC. Метод Collect() і GC. Коли ви відпустите останній об'єкт, метод WaitForPendingFinalizers(). Оскільки середовище виконання виконує збирання скарбів у колі RCW, GC. Метод Collect() змушує збирача скарбів запускатися та випускати будь-які посилання, які досі містить RCW. The GC. Метод Collect() намагається відклняти максимальну доступну пам'ять. Зверніть увагу, що це не гарантує, що всі пам'ять буде відкличуто.
Застосовується до
Ця стаття також стосується:
-
Microsoft Visual Basic .NET (усі випуски)
-
Microsoft Visual C# .NET (усі випуски)
-
Microsoft Office 2016 (усі випуски)
-
Microsoft Office 2013 (усі випуски)