在c#中发布PowerPoint Interop Com类成员实例

本文关键字:Com 成员 实例 Interop PowerPoint | 更新日期: 2023-09-27 18:14:08

我创建了一个简单的powerpoint插件,这是代码

pp.Application ppApplication = new pp.Application();
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
     ppApplication.PresentationOpen += new pp.EApplication_PresentationOpenEventHandler(ppApplication_PresentationOpen);
     ppApplication.PresentationClose += new pp.EApplication_PresentationCloseEventHandler(ppApplication_PresentationClose);
}
void ppApplication_PresentationOpen(pp.Presentation Pres)
{          
}
void ppApplication_PresentationClose(pp.Presentation Pres)
{
      GC.Collect();
      GC.WaitForPendingFinalizers();
       Marshal.FinalReleaseComObject(ppApplication);  
}

如果ppApplication是全局的,Power point永远不会关闭。我认为全局com对象不会以这种方式释放。我该怎么办?

在c#中发布PowerPoint Interop Com类成员实例

遵循这篇文章的建议释放COM对象的正确方式?

1) Declare & instantiate COM objects at the last moment possible.
2) ReleaseComObject(obj) for ALL objects, at the soonest moment possible.
3) Always ReleaseComObject in the opposite order of creation.
4) NEVER call GC.Collect() except when required for debugging.

你应该打电话给

pp.Application ppApplication = new pp.Application();
在Ribbon_Load

你在COM实例化和释放中也是不对称的——你在类初始化时实例化(即变量声明中的a = new()),但在表示结束时释放。关闭演示文稿和关闭应用程序是不一样的——功能区可能仍然可用,这将给你带来痛苦。

最后一点是,你永远不要解开你钩到COM对象的事件,你至少应该做

ppApplication.PresentationOpen -= new pp.EApplication_PresentationOpenEventHandler(ppApplication_PresentationOpen);
     ppApplication.PresentationClose -= new pp.EApplication_PresentationCloseEventHandler(ppApplication_PresentationClose);

释放事件处理程序,否则会有一些未死的引用。

您应该应用Dispose/Finalize模式来适当释放未托管的资源。这将保证一旦您的类被处置,所有非托管类成员(不是全局变量)将被释放。参见https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.100).aspx

using System;
using System.Runtime.InteropServices;
namespace PowerPointTestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            using (Container c = new Container())
            {
                Console.WriteLine("Opened..");
            }
            Console.WriteLine("Closed..");
        }
    }
    public class Container: IDisposable
    {
        Microsoft.Office.Interop.PowerPoint.Application pp = new Microsoft.Office.Interop.PowerPoint.Application();
        public Container()
        {
            pp.PresentationOpen += (pres)=>
            {
                //DoSomething
            };
            pp.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;  
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                pp.Quit();
                Marshal.FinalReleaseComObject(pp);
            }         
        }
        ~Container()
        {            
            Dispose(false);
        }
    }
}