zoukankan      html  css  js  c++  java
  • 关于ASP.NET中调用Excel组件不能结束进程的解决方法

            关于在asp.net中调用Excel组件不能结束进程的问题,常见的解决方法用的是下面这段代码

    wb.Close(null,null,null);
    app.Workbooks.Close();
    app.Quit();

    if(rng != null)
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
        rng 
    = null;
    }

    if(ws != null)
    {
    System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
        ws 
    = null;
    }

    if(wb != null)
    {  System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
        wb 
    = null;
    }

    if(app != null)
    { System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
    app 
    = null;
    }

    GC.Collect();

            虽然这段代码在配置正确的情况下能自动结束Excel进程,但是前提是在操作Excel时没有引发异常的情况下,如果有异常发生,那么Excel进程将不能结束(比如:引用了一个在Excel文件中不存在的文本框时就会出现“HRESULT 中的异常:0x800A03EC。”),这时就要借助Process类的Kill()方法来结束,下面是我写的测试代码:

    using System;
    using System.Diagnostics;
    using excel = Microsoft.Office.Interop.Excel;

    namespace ExcelTest
    {
        
    /// <summary>
        
    /// Excel的摘要说明。
        
    /// </summary>

        public class Excel
        
    {
            
    private DateTime beforeTime;            //Excel启动之前时间
            private DateTime afterTime;                //Excel启动之后时间

            excel.Application app;
            excel.Workbook wb;
            excel.Worksheet ws;
            excel.Range rng;
            excel.TextBox tb;

            
    public Excel(string templetPath)
            
    {
                
    //实例化一个Excel Application对象并使其可见
                beforeTime = DateTime.Now;
                app 
    = new excel.ApplicationClass();
                app.Visible 
    = true;
                afterTime 
    = DateTime.Now;

                wb 
    = app.Workbooks.Open(templetPath,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);
                ws 
    = (excel.Worksheet)wb.Worksheets.get_Item(1);
            }


            
    public void ExcelMethod()
            
    {
                rng 
    = ws.get_Range("B5","C7");
                rng.Merge(excel.XlAxisCrosses.xlAxisCrossesAutomatic);
                rng.Value2 
    = "Excel2003";

                rng 
    = ws.get_Range("D8","E11");
                rng.MergeCells 
    = true;
                rng.Value2 
    = "Excel2003";
                rng.HorizontalAlignment 
    = excel.XlHAlign.xlHAlignCenter;
                rng.VerticalAlignment 
    = excel.XlVAlign.xlVAlignCenter;

                rng 
    = ws.get_Range("A1",Type.Missing);
                rng.Value2 
    = 5;

                rng 
    = ws.get_Range("A2",Type.Missing);
                rng.Value2 
    = 7;

                
    for(int i=1;i<100;i++)
                
    {
                    
    string s = string.Concat("G",i.ToString());
                    rng 
    = ws.get_Range(s,Type.Missing);
                    rng.Value2 
    = i.ToString();
                }


                tb 
    = (excel.TextBox)ws.TextBoxes("文本框 1");
                tb.Text 
    = "作 者";

                tb 
    = (excel.TextBox)ws.TextBoxes("文本框 2");
                tb.Text 
    = "KLY.NET的Blog";

                tb 
    = (excel.TextBox)ws.TextBoxes("文本框 3");
                tb.Text 
    = "日 期";


                
    try
                
    {
                    tb 
    = (excel.TextBox)ws.TextBoxes("文本框 5");
                    tb.Text 
    = DateTime.Now.ToShortDateString();
                }

                
    catch
                
    {
                    
    //这里用Dispose()方法结束不了Excel进程,所有还是要用Process的Kill()方法配合使用
                    
    //                this.Dispose();
                    this.KillExcelProcess();
                    
    throw new Exception("不存在ID为\"文本框 5\"的文本框!");
                }

                
    finally
                
    {
                    
    //如果有异常发生,Dispose()方法放在这里也结束不了Excel进程
    //                this.Dispose();

                    
    //如果发生异常,在这里也可以结束Excel进程
    //                this.KillExcelProcess();
                }

            }


            
    /// <summary>
            
    /// 另存为Excel文件
            
    /// </summary>
            
    /// <param name="savePath">保存路径</param>

            public void SaveAsExcelFile(string savePath)
            
    {
                wb.SaveAs(savePath,excel.XlFileFormat.xlHtml,Type.Missing,Type.Missing,Type.Missing,Type.Missing,excel.XlSaveAsAccessMode.xlExclusive,Type.Missing,Type.Missing,Type.Missing,Type.Missing,Type.Missing);
            }


            
    /// <summary>
            
    /// 结束Excel进程
            
    /// </summary>

            public void KillExcelProcess()
            
    {
                Process[] myProcesses;
                DateTime startTime;
                myProcesses 
    = Process.GetProcessesByName("Excel");

                
    //得不到Excel进程ID,暂时只能判断进程启动时间
                foreach(Process myProcess in myProcesses)
                
    {
                    startTime 
    = myProcess.StartTime;

                    
    if(startTime > beforeTime && startTime < afterTime)
                    
    {
                        myProcess.Kill();
                    }

                }

            }


            
    /// <summary>
            
    /// 如果对Excel的操作没有引发异常的话,用这个方法可以正常结束Excel进程
            
    /// 否则要用KillExcelProcess()方法来结束Excel进程
            
    /// </summary>

            public void Dispose()
            
    {
                wb.Close(
    null,null,null);
                app.Workbooks.Close();
                app.Quit();

                
    //注意:这里用到的所有Excel对象都要执行这个操作,否则结束不了Excel进程
                if(rng != null)
                
    {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
                    rng 
    = null;
                }

                
    if(tb != null)
                
    {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(tb);
                    tb 
    = null;
                }

                
    if(ws != null)
                
    {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
                    ws 
    = null;
                }

                
    if(wb != null)
                
    {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
                    wb 
    = null;
                }

                
    if(app != null)
                
    {
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                    app 
    = null;
                }


                GC.Collect();
            }

        }

    }

            这段代码能很好的解决Excel进程不能正常结束的问题,如果主机操作系统不是服务器版的话,那么就要借助于ntsd -c q -p pid命令来结束。
            还有一个问题的关于Excel组件访问权限的配置,一定要在组件服务里面正确配置,否则结束不了Excel进程,具体的配置方法在我项目的doc文件夹下;在我前面的文章里面介绍了在web.config文件里面加入假扮用户的方法,但是经我测试发现这种方法虽然可以访问Excel组件,但是结束不了进程,除非用Kill方法强行结束。

    点这里下载ExcelTest.rar

  • 相关阅读:
    POJ 3258 (NOIP2015 D2T1跳石头)
    POJ 3122 二分
    POJ 3104 二分
    POJ 1995 快速幂
    409. Longest Palindrome
    389. Find the Difference
    381. Insert Delete GetRandom O(1)
    380. Insert Delete GetRandom O(1)
    355. Design Twitter
    347. Top K Frequent Elements (sort map)
  • 原文地址:https://www.cnblogs.com/lingyun_k/p/271796.html
Copyright © 2011-2022 走看看