C#中通过com组件操作excel不能关闭的问题

来源:互联网 发布:js对象概念 编辑:程序博客网 时间:2024/05/17 05:05

问题:

当用如下代码操作完Excel,虽然调用了Application的Quit()方法,但发现Excel进程并没退出。

           object missing = System.Reflection.Missing .Value;            Application app = new Application();            app.Visible = false ;            app.UserControl = true ;            Workbook wb = app.Workbooks.Open(path, missing, true , missing, missing, missing, missing,                        missing, missing, true , missing, missing, missing, missing, missing);            Worksheet ws = (Worksheet )wb.Worksheets.get_Item(1);            Console .WriteLine(ws.Cells[2,1].Value);            ws.Close();            ws = null;            app.Quit();            app = null;

结果:



原因:
When Visual Studio .NET calls a COM object from managed code, it automatically creates a Runtime Callable Wrapper (RCW). The RCW marshals calls between the .NET application and the COM object. The RCW keeps a reference count on the COM object. Therefore, if all references have not been released on the RCW, the COM object does not quit.

解决方案:

1、为每一个对象定义一个变量。
例如:
把这段代码
Workbook wb = wbs.Open(path, missing, true , missing, missing, missing, missing,
                        missing, missing, true , missing, missing, missing, missing, missing);
改为
Workbooks wbs = app.Workbooks;
Workbook wb = wbs.Open(path, missing, true , missing, missing, missing, missing,
                        missing, missing, true , missing, missing, missing, missing, missing);

2、当使用完com对象对其循环调用System.Runtime.InteropServices.Marshal.ReleaseComObject 直到返回值为0
3、设置变量位null
4、调用Quit方法通知服务器关闭
5、调用GC .Collect();

最终:
把上边的代码修改为:
        public static void ExcelRead(string path)        {            object missing = System.Reflection.Missing.Value;            Application app = new Application();            app.Visible = false;            app.UserControl = true;            Workbooks wbs = app.Workbooks;            Workbook wb = wbs.Open(path, missing, true, missing, missing, missing, missing,                        missing, missing, true, missing, missing, missing, missing, missing);            Sheets wss = wb.Worksheets;             Worksheet ws = (Worksheet)wss.get_Item(1);            Console.WriteLine(ws.Cells[2,1].Value);            NAR(ws);            ws = null;            NAR(wss);            wss = null;            wb.Close();            NAR(wb);            wb = null;            wbs.Close();            NAR(wbs);            wbs = null;            app.Quit();            NAR(app);            app = null;            GC.Collect();        }        private static void NAR(object o)        {            try            {                while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;            }            catch            { }            finally            {                o = null;            }        }    
结果能正常关闭Excel进程。

0 0
原创粉丝点击