簡體   English   中英

在C#中發布PowerPoint Interop Com類成員實例

[英]Release PowerPoint Interop Com class member instance in C#

我為Powerpoint創建了一個簡單的addIn,這是代碼

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是全局的,則Powerpoint永遠不會關閉。 我認為全局com對象不會以這種方式釋放。 我該怎么辦?

您應該應用“處置/完成”模式來正確釋放非托管資源。 這將確保一旦處置了您的班級,將釋放所有非托管班級成員(而不是全局變量)。 參見https://msdn.microsoft.com/zh-cn/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);
        }
    }
}

遵循本文中的建議釋放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);

取消分配事件處理程序,否則您將有一些亡靈引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM