office二次开发,Com对象自动释放

office的每个对象引用必须要显示释放,才能将所有内存释放,自动关闭office进程。
类似于下面的代码:
Chart.Title.Text=”test”;
Title对象是无法释放的,我们必须写成:
Chart chart=GetChartObj(Name);
Title title=Chart.Title;
Title.Text=”test”;
Marshal.FinalReleaseComObject(title); 
Marshal.FinalReleaseComObject(chart); 
也就是对每个对象的访问,必须经过ReleaseComObject()才可以关闭office进程。
下边的就解决这个问题。
 /// <summary>
    /// Com封装对象,用于com对象的释放
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <author>
    /// tang jing bo
    /// </author>
    /// <remarks>
    /// tangj15 2011-11-4
    /// </remarks>
    public class ComWrap<T> : Releasable where T : class
    {
        private T _needReleaseObj;
        private bool disposed;

        /// <summary>
        /// Initializes a new instance of the <see cref="ComWrap&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="needReleaseObj">The need release obj.</param>
        public ComWrap(T needReleaseObj)
        {
            _needReleaseObj = needReleaseObj;
        }

        /// <summary>
        /// 获取Com对象引用
        /// </summary>
        public T Target
        {
            get { return _needReleaseObj; }
        }

        /// <summary>
        /// Performs an explicit conversion from <see cref="T"/> to <see cref="System.ComWrap&lt;T&gt;"/>.
        /// </summary>
        /// <param name="comObject">The COM object.</param>
        /// <returns>
        /// The result of the conversion.
        /// </returns>
        public static explicit operator ComWrap<T>(T comObject)
        {
            return new ComWrap<T>(comObject);
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="System.ComWrap&lt;T&gt;"/> to <see cref="T"/>.
        /// </summary>
        /// <param name="wrap">The wrap.</param>
        /// <returns>
        /// The result of the conversion.
        /// </returns>
        public static implicit operator T(ComWrap<T> wrap)
        {
            return wrap.Target;
        }
        /// <summary>
        /// Wraps the specified COM object.
        /// </summary>
        /// <param name="comObject">The COM object.</param>
        /// <returns></returns>
        public static ComWrap<T> Wrap(T comObject)
        {
            return new ComWrap<T>(comObject);
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (!disposed)
            {
                try
                {
                    if (disposing)
                    {
                    }
                    if (_needReleaseObj != null)
                    {
                        Marshal.FinalReleaseComObject(_needReleaseObj);
                        _needReleaseObj = null;
                    }
                    disposed = true;
                }
                finally
                {
                    // Call Dispose on your base class.
                    base.Dispose(disposing);
                }
            }
        }

再写一个扩展类方便com对象的封装调用

/// <summary>
    /// Com释放扩展
    /// </summary>
    /// <author>
    /// Tang Jing bo
    /// </author>
    /// <remarks>
    /// tangj15 2011-11-4
    /// </remarks>
    public static class ComObjectDisposeExtension
    {
        /// <summary>
        /// 返回将Com组件包装后对象,需要显示的调用Dispose()方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="comObject">The COM object.</param>
        /// <returns></returns>
        public static ComWrap<T> Wrap<T>(this T comObject) where T : class
        {
            return new ComWrap<T>(comObject);
        }
        /// <summary>
        /// 返回将Com组件包装后对象,需要显示的调用Dispose()方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="comObject">The COM object.</param>
        /// <returns></returns>
        public static ComWrap<T> Wrap<T>(this object comObject) where T : class
        {
            return new ComWrap<T>((T)comObject);
        }
        /// <summary>
        /// 将Com组件包装后,执行action的代码,并且执行完后自动释放
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="comObject">The COM object.</param>
        /// <param name="action">The action.</param>
        public static void WrapRun<T>(this T comObject, Action<ComWrap<T>> action) where T : class
        {
            using (var o = new ComWrap<T>(comObject))
                action(o);
        }
        /// <summary>
        /// 将Com组件包装后,执行action的代码,并且执行完后自动释放
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="comObject">The COM object.</param>
        /// <param name="action">The action.</param>
        public static void WrapRun<T>(this object comObject, Action<ComWrap<T>> action) where T : class
        {
            WrapRun((T)comObject, action);
        }
        /// <summary>
        /// 将Com组件包装后,执行并返回func的值,返回前自动释放com对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TRet">The type of the ret.</typeparam>
        /// <param name="comObject">The COM object.</param>
        /// <param name="func">The func.</param>
        /// <returns></returns>
        public static TRet WrapGet<T, TRet>(this T comObject, Func<ComWrap<T>, TRet> func) where T : class
        {
            using (var o = new ComWrap<T>(comObject))
                return func(o);
        }

        /// <summary>
        /// 将Com组件包装后,执行并返回func的值,返回前自动释放com对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TRet">The type of the ret.</typeparam>
        /// <param name="comObject">The COM object.</param>
        /// <param name="func">The func.</param>
        /// <returns></returns>
        public static TRet WrapGet<T, TRet>(this object comObject, Func<ComWrap<T>, TRet> func) where T : class
        {
            return WrapGet((T)comObject,func);
        }
    }
 
我们可以这样调用:

using (ComWrap<Slides> slides = Presentation.Target.Slides.Wrap())
            {

//….

}

也可以使用扩展方法:

Presentation.Target.Slides.WrapRun(slide=>{..do});

原文地址:https://www.cnblogs.com/68681395/p/2262147.html