zoukankan      html  css  js  c++  java
  • 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});

  • 相关阅读:
    上采样和下采样
    二、决策树算法
    一、实现贝叶斯算法
    Centos7 安装vscode
    Centos安装IDEA
    Centos设置自带中文输入法
    Centos 安装mysql
    Centos,tomcat
    Centos 7 安装JDK
    Centos7 安装rar,unrar,zip,unzip
  • 原文地址:https://www.cnblogs.com/68681395/p/2262147.html
Copyright © 2011-2022 走看看