Проблемы
При автоматизации Microsoft Office от Microsoft Visual Basic .NET или Microsoft Visual C# .NET приложение Office не выходит из системы при вызове метода Quit.
Причина
Когда Visual Studio .NET вызывает объект COM из управляемого кода, автоматически создается оружейник с возможностью вызова в режиме runtime (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.В цикле. ReleaseComObject, пока не будет возвращено 0, когда вы закончите работу с объектом. System.Runtime.InteropServices.Разрежает количество ссылок на RCW. При этом цикл позволяет освободить компонент COM независимо от того, сколько раз он повторно вошел в clr.
-
Чтобы отпустить ссылку на переменную, задаем для нее значение Nothing или Null.
-
Используйте метод Quit объекта Office приложения, чтобы сообщить серверу о том, что он закрыт.
Статус
Такое поведение является особенностью данного продукта.
Дополнительная информация
Действия для воспроизведения поведения
-
Начните Visual Studio .NET.
-
В меню Файл выберите пункт Новый и нажмите кнопку Project. В Visual Basic проектов выберите Windows приложение и нажмите кнопку ОК.
Примечание По умолчанию создается форма 1. -
Добавьте ссылку на библиотеку Microsoft Excel объекта. Для этого выполните следующие действия:
-
В меню Project ссылку добавить ссылку.
-
На вкладке COM найдите библиотеку объектов для Excel и нажмите кнопку Выбрать.
For Microsoft Excel 2002: Microsoft Excel 10.0 Object LibraryNote Если вы еще не сделали этого, рекомендуем скачать и установить сборки Microsoft Office XP Primary Interop Assemblies
(PIAs).
Дополнительные сведения о Office XP можно найти в следующей статье базы знаний Майкрософт:328912 Microsoft Office xp: основные сборки (PIAs) доступны для скачивания
Для Microsoft Office Excel 2003: Microsoft Excel 11.0 Object Library -
Нажмите кнопку ОК в диалоговом окне Добавление ссылок, чтобы принять выбор.
-
-
В меню Вид выберите пункт Панели инструментов и перетащите кнопку управления в форму 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, со ссылкой на код функции СЛВП(), с помощью этой функции:
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.Services.Service.FinalReleaseComObject, а не циклику звонков System.Runtime.InteropServices.Вкл.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 (все выпуски)