zoukankan      html  css  js  c++  java
  • 关闭excel进程

    以前做web 程序的时候在.net环境下有时候是非常难将当前的excel或者word线程关闭,有时候在程序里面执行完excel关闭并且释放相关资源,但在服务器端的excel进程要等一会才能被关闭掉。如果用户在客户端平凡对excel操作(在很短的时间内),即使在程序里面控制了对excel组件的释放和回收,但是有可能服务器端有N个excel进程没有被关闭,造成服务器可能死掉。我相信有过对excel编程的朋友对关闭excel进程特别是在web 觉得是件很麻烦的事情。网上也有很多关闭excel的例子,但是发现N多是相互转载,都是用同一种办法,而且效果也不是很好。

    这几天看到别人用System.Diagnostics.Process的时候想到了一个新方法。下面是我的具体做法:
    1: 在打开或者新建excel,word的时候,先将当前进程里的word,excel进程的ID记录下来(这些有可能是属于用户已经打开的word或者excel进程,最后删除的时候这些进程是不能kill 掉的

    //在打开excel前,将系统里面已经存在的excel进程进程ID保存起来
    List<int> intList = new List<int>();

    foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
        {
            if (p.ProcessName.ToUpper() == "EXCEL")
                {
                    intList.Add(p.Id);
                }
        }

    2: 我们的程序打开或者新建excel的操作,有可能还有其他的操作,我这里只简单的列出了基本操作。
    Application app = new Application();
    Workbook workbook = app.Workbooks.Open(FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

    Worksheet worksheet = (Worksheet)workbook.Worksheets[1];

    workbook.Close(Type.Missing, Type.Missing, Type.Missing);
    app.Quit();

    3:关闭就是如何关闭刚才新建的excel进程

    //先用系统提供的方法对系统资源释放,这种做法是大家常用的方法
    System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
    GC.Collect();

    //以下是我的新方法,如果还对象还没有释放的话kill 掉新线程
    if (app!=null)
    {

                    foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
                    {   
                        //先判断当前进程是否是excel                 
                        if (p.ProcessName.ToUpper() == "EXCEL")
                        {
                            //需要判断这个进程是用户打开的还是属于新建的进程,如果用户没有打开过excel,则直接kill掉这个进程
                            if (intList != null && intList.Count > 0)
                            {
                                //用来标志是否是程序新建的
                                bool bNewID=true;

                                foreach (int existId in intList)
                                {
                                    if (existId == p.Id)
                                    {
                                        bNewID = false;
                                        break;
                                    }
                                }
                                //如果没有匹配到的话,说明是程序新建的,则删除他
                                if (bNewID == true)
                                {
                                    p.Kill();
                                }
                            }
                            //用户都没有打开过excel进程,则直接kill掉他
                            else
                            {
                                p.Kill();
                            }
                        }
                    }

    }

    以上方法就是我的方法。不过我个人觉得还有一点没有做好。 如果程序里面对excel操作的时间很长的话,那可能存在一点风险。因为程序很复杂造成对excel 操作很长时间的话,用户有可能在这段时间内又刚好打开了一个excel文件,这样程序在执行的时候有可能将用户这个进程也kill掉。所以以上我说的方法适合对excel操作时间比较短的情况.
    看到这里你可能会说为什么不取新建时application的时候他的进程ID,操作完之后通过System.Diagnostics.Process.GetProcessById() 方法获取到这个Process,其实我开始也想通过这个方法来处理。无奈微软没有提供获取新建application的进程ID的方法。

    希望以上方法对那些关闭excel进程头痛的朋友有帮助
    如果大家觉得有更好的建议或者有新的方法麻烦告诉我,谢谢!以下是我的博客地址:http://farrell.cnblogs.com/








  • 相关阅读:
    观察者模式(Observer)
    记负均正
    自守数
    等差数列
    字符统计
    Linux 第四次上机收获
    关于java的类加载(血泪史)
    vi常用操作与命令【持续更新中】
    P3-2017级算法第三次上机 B SkyLee逛漫展
    P3-2017级算法第三次上机 A 水水的二分查找
  • 原文地址:https://www.cnblogs.com/farrell/p/1053349.html
Copyright © 2011-2022 走看看