在winform中用webbrowser打开一个Excel后,(webbrowser.Navagate(path))无法释放进程里的Excel.exe资源,怎么办?
不能使用进程 process.kill(Excel.exe);因为这样会关闭其它的Excel进程

解决方案 »

  1.   

    楼主是怎么操作这个Excel的代码内打开就close掉进程开的就Abort
      

  2.   

    kill掉execel的那个进程。就全部释放了。
      

  3.   

    public static void Kill(Microsoft.Office.Interop.Excel.Application excel)
            {
                IntPtr t = new IntPtr(excel.Hwnd); //得到这个句柄,具体作用是得到这块内存入口            int k = 0;
                GetWindowThreadProcessId(t, out k); //得到本进程唯一标志k
                System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(k); //得到对进程k的引用
                p.Kill(); //关闭进程k
            }
      

  4.   

    楼上的仁兄,public static void Kill(Microsoft.Office.Interop.Excel.Application excel) 
    这个方法我看过,关键是怎么传参?我打开的Excel是根据一个路径,如:C:\test.xls
    怎么写?
      

  5.   

    用流的方式把excel中的数据导入webbrowser
      

  6.   

    LS说KILL进程的朋友们···我说你们真行!!!如果用户是administrator还行,如果不是怎么办??你是没有权限KILL滴!!!
    object objmissing = System.Reflection.Missing.Value;Excel.ApplicationClass application = new ApplicationClass();
    Excel.Workbook book = application.Workbooks.Add(objmissing);
    Excel.Worksheet sheet = (Excel.Worksheet)book.Worksheets.Add(objmissing,objmissing,objmissing,objmissing);//操作过程 ^&%&×&……&%&&……//释放
    sheet.SaveAs(path,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing,objmissing);
    System.Runtime.InteropServices.Marshal.ReleaseComObject((object)sheet);
    System.Runtime.InteropServices.Marshal.ReleaseComObject((object)book);
    application.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject((object)application);
    System.GC.Collect();有一点,在网上你是找不到滴···纯属经验:
    如果你要写的Excel是多个Sheet的话,那么你最好写个函数:
    比如 private bool overdue_report_sub(Excel.Worksheet sheet)
    将sheet的对象传进去,在这个函数中进行操作,函数过程只写Sheet的操作过程,释放还是放在外面。如果你不这样做的话,那么,恭喜你,你还是释放不掉。但是如果只有一个Sheet操作的话,你就可以不用写这个函数了,只是在整个函数体中进行创建和释放。
      

  7.   

    我没有创建Excel表
    我用的是在Winform中,通过Webbrowser打开已经存在得Excel
    我打开的Excel是根据一个路径,如:C:\test.xls 
    this.webbrowser1.Navegage("C:\test.xls");
    在进程里就有了,Excel.exe进程,如何关闭它!~
      

  8.   

    this.webbrowser1.dispose();我用过了,也无法及时释放!
      

  9.   


    Excel.ApplicationClass xlsApp = null;
    Excel.Workbook xlsBook = null;
    Excel.Worksheet xlsSheet = null;try
    {
        xlsApp = new Excel.ApplicationClass();
        xlsApp.AlertBeforeOverwriting = false;
        xlsApp.DisplayAlerts = false;    xlsBook = xlsApp.Workbooks.Open(excelFile, Missing.Value, Missing.Value, Missing.Value, pswStr, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);    xlsBook.SaveAs(excelFileName, Missing.Value, "", Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
    }
    catch (Exception err)
    {
        MessageBox.Show("操作Excel文件异常: " + Environment.NewLine + err.Message);
    }
    finally
    {
        xlsSheet = null;    if (xlsBook != null)
        {
            xlsBook.Close(false, Missing.Value, Missing.Value);
            xlsBook = null;
        }    if (xlsApp != null)
        {
            xlsApp.Quit();
            xlsApp = null;
        }
    }上面代码中,excelFile为需要打开的文件,excelFileName为要保存的文件,pswStr为打开Excel文件的口令。另存是不保存口令。
      

  10.   

    在我的界面中,没有以下的东东:
    Excel.ApplicationClass xlsApp = null;
    Excel.Workbook xlsBook = null;
    Excel.Worksheet xlsSheet = null;我只是用webbrowser1打开了一个test.xls而已,在进程里就有了Excel.exe进程,如何关闭它!(不采用p.kill(),因为这样可能关闭其他的Excel进程)
    private void button1_Click(object sender,EventArgs e)
    {
     this.openFileDialog1.ShowDialog();
     this.webbrowser1.Navigate(this.openFileDialog1.FileName);
    }
      

  11.   

    给你个解题思路吧,
    首先找到Excel进程开始调入内存的地方,你的程序中可能在 (webbrowser.Navagate(path))处,
    用数组记录下此时所有的Excel 进程的进程号(或这些进程的标志)(这个数组有可能为空,也有可能不是)
    然后,执行下一步程序产生新的Excel,用另一个数组记录此时的所有Excel的进程号,
    比对这两个数组的内容就知道刚才产生的进程号是什么了,
    然后再kill 掉这个进程就可以了
      

  12.   

    时间关系,只能给你些参考代码          try
                {
                    Process [] xlProcess= Process.GetProcessesByName("Excel");
                    foreach(Process tProcess in  xlProcess)
                    {   
                        tProcess.Kill();
                    }
                }
                catch(Exception exp2)
                {
                    MessageBox.Show(exp2.ToString());
                }
      

  13.   

    楼上的仁兄,我说过不能通过进程名,来kill的,因为我不想杀死计算机中其他的Excel进程!~
      

  14.   

    现在的问题可以简化成这样:
    通过webbrowser控件打开一个test.xls后,如何捕捉其在进程中生成的PID,因为每个进程的PID是唯一的,我可以根据PID来Kill杀死它!~~
    那位大侠能帮我解决哈,谢谢了!~~~
      

  15.   


      System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheets);   
      System.Runtime.InteropServices.Marshal.ReleaseComObject(worksheet);   
      ...   
      System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);   
      System.Runtime.InteropServices.Marshal.ReleaseComObject(range);   
      worksheets=null;   
      worksheet=null;   
      ...   
      excelApp=null;   
      range=null;   
        
      把操作Excel文件用到的对象实例全部释放。   
      然后资源回收!   
      GC.Collect();   流用完后要关闭;word文档关闭要退出并nothing  
      
      

  16.   

    我写的多标签的浏览器试过了,关闭一个标签后,GC.Collect()下就关闭了如果不执行就一直关闭不了,可能是没有执行finalize,而且我们不能直接调用对象的finalize方法对于非托管资源的对象回收:
    他们的一引用针存放在一个终结链表中(需要执行finalize),垃圾回收时会吧这些对象引用移动到终结可达队列,但这些对象还在GC堆上。
    然后特殊的线程会清理终结可达队列,然后调用他们的finalize方法释放资源。等到下一次垃圾回收时,已经没有引用了,然后才会执行垃圾回收,回收这些对象。我程序中用dispose();来关闭资源,但是还是无法回收
    后来是用了GC.ReRegisterForFinalize(webbrowers);这个是请求系统调用webbrowers的finalize方法。这样就可以关闭,这个效果和GC.Collect()以及关闭程序是一样的,另外一种方法是关闭后新建多个对象,使得系因为0代被填充满而进行垃圾回收,这个时候就会关闭。因为他们都会导致finalize方法执行。所以没有回收应该是finalize没有执行的原因。不知道我说的对不对!
      

  17.   

    Finalize是CRL提供的一个机制, 它保证如果一个类实现了Finalize方法,那么当该类对象被垃圾回收时,垃圾回收器会调用Finalize方法.而该类的开发者就必须在Finalize方法中处理 非托管资源的释放. 但是什么时候会调用Finalize由垃圾回收器决定,该类对象的使用者(客户)无法控制.从而无法及时释放掉宝贵的非托管资源.由于非托管资源是比较宝贵了,所以这样会降低性能. Dispose(bool disposing)不是CRL提供的一个机制, 而仅仅是一个设计模式(作为一个IDisposable接口的方法),它的目的是让供类对象的使用者(客户)在使用完类对象后,可以及时手动调用非托管资源的释放,无需等到该类对象被垃圾回收那个时间点.这样类的开发者就只需把原先写在Finalize的释放非托管资源的代码,移植到Dispose(bool disposing)中.  而在Finalize中只要简单的调用 "Dispose(false)"就可以了.
    因为没有对对象执行垃圾回收所以没有调用到Finalize方法,也就无法释放非托管资源。这是MSDN上写的Dispose写的:
    每次释放对 Component 的最后一个引用前,均应调用 Dispose。否则,在垃圾回收器调用 Component 对象的 Finalize 方法之前,正在使用的资源不会被释放。他的意思也是调用了Dispose应该可以回收的,但这里没有回收,个人觉得可能是webbrowers这里写的有点问题。具体可以看MSDN上“清理非托管资源 ”,垃圾回收 框架设计上介绍的比较清楚
      

  18.   

       大家好,我这边也写了一个程序,在32位机windows server 2003中测试通过了,在服务器windows server 2008中,该程序通过不了,只能够第一次成功,第二次就提示该文件正在被使用。我释放资源的代码如下:
            public void Close()//关闭一个Excel对象,销毁对象 
            {
                //wb.Save(); 
                wb.Close(Type.Missing, Type.Missing, Type.Missing);
                
                wbs.Close();
                app.Workbooks.Close();
                app.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(wbs);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);            wb = null;
                wbs = null;
                app = null;
               
                GC.Collect();
            }
    发现了这个问题后,我发现程序的进行为:excel.exe *32,我就写了一个杀死该进程的程序,代码如下:
     public static  void killProcess(string processName)
            {
                foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
                {
                    if (p.ProcessName.Trim ().ToLower().Equals(processName.Trim () .ToLower ()))
                    {
                        p.Kill();
                    }
                }
            }
    结果是能够把excel.exe *32进程给杀掉,但是还是一样提示该文件正在被使用,我就直接从系统中删除该文件,结果搞w3wp.exe正在使用该文件,不知道大家见过该问题没有,各位帮帮忙啊,这个问题我已经3天都没有搞定了,郁闷中
      

  19.   

    你试试这个代码。。      
          finally {
                    worksheet = null;
                    wb.Close(Type.Missing, Type.Missing, Type.Missing);
                    wbs.Close();
                    app.Quit();
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(wbs);
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                    wbs = null;
                    wb = null;
                    app = null;
                    GC.Collect();      
                }