Приложение. Выход () метод, не удающийся очистить процесс

Я видел много сообщений, возвращенных из поиска 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();

Затем Выход () не будет работать. Что-то об открытии презентации, даже если я затем закрываю его, предотвращает Выход () от работы, это появляется.

У кого-либо есть какие-либо мысли о том, как я могу заставить приложение выходить корректно?

10
задан unholysampler 7 July 2010 в 17:25
поделиться

2 ответа

Следующий KB Aritcle может помочь вам разобраться в проблеме. http://support.microsoft.com/kb/317109

Вам может потребоваться явный вызов System.Runtime.InteropServices.Marshal.ReleaseComObject в вашем экземпляре ppt.

6
ответ дан 3 December 2019 в 20:39
поделиться

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. Я не могу рекомендовать и это. В конце концов, он выйдет из программы. Не беспокойтесь об этом.

3
ответ дан 3 December 2019 в 20:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: