前几天有个同事问我一个问题,就是如何使用子线程打开PPTX文件。开始时我并没有觉得这是个什么大问题。因为我觉得这个主要的难点在于注意线程上下文的切换上。不过开始做个Demo后感觉有点困惑了,主要集中在Application.Quit()方法上。
因为需求里希望打开PPT文件进行播放幻灯片,当幻灯片结束时需要关闭PPT文件。这个需求很合理,因为我们的程序其实就是个打开幻灯片的外壳,如果幻灯片结束后PPT程序还挂在任务栏上,那直接使用PPT不就行了嘛,呵呵。
直入主题啦。使用的程序集就是Microsoft.Office.Interop.PowerPoint.dll,从MSDN的文档上找到了两个事件可以解决关闭的时机,SlideShowEnd和PresentationClose事件。
SlideShowEnd事件:一个幻灯片播放结束后发生,最后一次SlideShowNextSlide事件发生后立即发生。(Occurs after a slide show ends, immediately after the last SlideShowNextSlide event occurs.)
PresentationClose事件:任何打开的ppt关闭之前立即发生,当ppt从Presentations集合移除时发生。(Occurs immediately before any open presentation closes, as it is removed from the Presentations collection.)
从说明中选择在SlideShowEnd事件里关闭PPT文件。
var _application = new Microsoft.Office.Interop.PowerPoint.Application();
_application.SlideShowEnd += pres=>
{
pres.Close();
_application.Quit();
};
第一次打开一个文件并结束幻灯片时一切顺利,但是重复几次同样的操作,就会报出"Application (unknown member) : Invalid request. This operation cannot be performed in this event handler."的COMException异常。先后进行了多次修改调用的位置(不使用子线程和使用子线程调用),但是总是运行到Quit方法时报错,从Google上也没有找到明确的答案,只是说COM对象是出于STA模式下。