Я видел много сообщений, возвращенных из поиска Google об этом, но ни одно из решений, на которые ссылаются в них, не разрешает это для меня. Так, я думал, что буду судить меня.
После этого блока кода:
PowerPoint.Application powerPoint = new Microsoft.Office.Interop.PowerPoint.Application();
powerPoint.Visible = Office.MsoTriState.msoTrue;
Microsoft.Office.Interop.PowerPoint.Presentation ppt = null;enter code here
Я могу выпустить ppt. Выход (); команда и Powerpoint закроются, и никакой Процесс не оставляют, работая.
Однако, если после этого кода я делаю это:
ppt = powerPoint.Presentations.Open(localCopyOfPPT,
Microsoft.Office.Core.MsoTriState.msoCTrue,
Microsoft.Office.Core.MsoTriState.msoTriStateMixed,
Microsoft.Office.Core.MsoTriState.msoTrue);
ppt.Close();
powerPoint.Quit();
Затем Выход () не будет работать. Что-то об открытии презентации, даже если я затем закрываю его, предотвращает Выход () от работы, это появляется.
У кого-либо есть какие-либо мысли о том, как я могу заставить приложение выходить корректно?
Следующий KB Aritcle может помочь вам разобраться в проблеме. http://support.microsoft.com/kb/317109
Вам может потребоваться явный вызов System.Runtime.InteropServices.Marshal.ReleaseComObject в вашем экземпляре ppt.
powerPoint.Presentations.Open(...)
Обратите внимание на использование объекта Presentations. COM использует ручное управление памятью, основанное на подсчете ссылок, каждый интерфейс COM имеет метод AddRef() и Release(). Вызов AddRef происходит автоматически, когда вы получаете объект. Когда вы закончите работу с ним, вы должны вызвать метод Release(). Использование объекта Presentations здесь добавляет ссылку на объект Presentations. Который, в свою очередь, добавляет ссылку на внутренний объект приложения.
Это очень несовместимо с управлением памятью в .NET framework. Оно осуществляется автоматически, сборщик мусора заботится об этом. Что он делает и для COM-объектов, в обертке interop есть финализатор, он уменьшает счетчик ссылок, когда видит, что на COM-объект не осталось .NET ссылок.
Возможно, вы понимаете, к чему это ведет: PowerPoint не может выйти, пока все ссылки на объект не будут освобождены. А это не может произойти, пока не запустится сборщик мусора и не завершится поток финализатора. Ваш вызов метода Quit() не заставляет запуститься сборщик мусора. Это может сделать только GC.Collect() + GC.WaitForPendingFinalizers.
Вы также можете воспользоваться ручным подходом. Для этого нужно выполнить Marshal.ReleaseComObject(). Это трудно сделать правильно, если учесть, что в вашем коде нигде не хранится ссылка на объект Presentations. Вам придется полностью переписать свой код, чтобы отслеживать эти ссылки и вызывать ReleaseComObject() для них.
Я не могу рекомендовать это. Если вы действительно очень хотите, чтобы PowerPoint вышел из программы, то лучший способ - убедиться, что все ваши ссылки нулевые, и вызвать GC.Collect() и GC.WFPF. Я не могу рекомендовать и это. В конце концов, он выйдет из программы. Не беспокойтесь об этом.