关于ASP.NET中调用Excel组件不能结束进程的解决方法

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

None.gif wb.Close( null , null , null );
None.gifapp.Workbooks.Close();
None.gifapp.Quit();
None.gif
None.gif
if (rng  !=   null )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
InBlock.gif    rng 
= null;
ExpandedBlockEnd.gif}

None.gif
if (ws  !=   null )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gifSystem.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
InBlock.gif    ws 
= null;
ExpandedBlockEnd.gif}

None.gif
if (wb  !=   null )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {  System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
InBlock.gif    wb 
= null;
ExpandedBlockEnd.gif}

None.gif
if (app  !=   null )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif { System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
InBlock.gifapp 
= null;
ExpandedBlockEnd.gif}

None.gifGC.Collect();
None.gif

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

None.gif using  System;
None.gif
using  System.Diagnostics;
None.gif
using  excel  =  Microsoft.Office.Interop.Excel;
None.gif
None.gif
namespace  ExcelTest
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// Excel的摘要说明。
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    public class Excel
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
private DateTime beforeTime;            //Excel启动之前时间
InBlock.gif
        private DateTime afterTime;                //Excel启动之后时间
InBlock.gif

InBlock.gif        excel.Application app;
InBlock.gif        excel.Workbook wb;
InBlock.gif        excel.Worksheet ws;
InBlock.gif        excel.Range rng;
InBlock.gif        excel.TextBox tb;
InBlock.gif
InBlock.gif        
public Excel(string templetPath)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//实例化一个Excel Application对象并使其可见
InBlock.gif
            beforeTime = DateTime.Now;
InBlock.gif            app 
= new excel.ApplicationClass();
InBlock.gif            app.Visible 
= true;
InBlock.gif            afterTime 
= DateTime.Now;
InBlock.gif
InBlock.gif            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);
InBlock.gif            ws 
= (excel.Worksheet)wb.Worksheets.get_Item(1);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void ExcelMethod()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            rng 
= ws.get_Range("B5","C7");
InBlock.gif            rng.Merge(excel.XlAxisCrosses.xlAxisCrossesAutomatic);
InBlock.gif            rng.Value2 
= "Excel2003";
InBlock.gif
InBlock.gif            rng 
= ws.get_Range("D8","E11");
InBlock.gif            rng.MergeCells 
= true;
InBlock.gif            rng.Value2 
= "Excel2003";
InBlock.gif            rng.HorizontalAlignment 
= excel.XlHAlign.xlHAlignCenter;
InBlock.gif            rng.VerticalAlignment 
= excel.XlVAlign.xlVAlignCenter;
InBlock.gif
InBlock.gif            rng 
= ws.get_Range("A1",Type.Missing);
InBlock.gif            rng.Value2 
= 5;
InBlock.gif
InBlock.gif            rng 
= ws.get_Range("A2",Type.Missing);
InBlock.gif            rng.Value2 
= 7;
InBlock.gif
InBlock.gif            
for(int i=1;i<100;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
string s = string.Concat("G",i.ToString());
InBlock.gif                rng 
= ws.get_Range(s,Type.Missing);
InBlock.gif                rng.Value2 
= i.ToString();
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            tb 
= (excel.TextBox)ws.TextBoxes("文本框 1");
InBlock.gif            tb.Text 
= "作 者";
InBlock.gif
InBlock.gif            tb 
= (excel.TextBox)ws.TextBoxes("文本框 2");
InBlock.gif            tb.Text 
= "KLY.NET的Blog";
InBlock.gif
InBlock.gif            tb 
= (excel.TextBox)ws.TextBoxes("文本框 3");
InBlock.gif            tb.Text 
= "日 期";
InBlock.gif
InBlock.gif
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                tb 
= (excel.TextBox)ws.TextBoxes("文本框 5");
InBlock.gif                tb.Text 
= DateTime.Now.ToShortDateString();
ExpandedSubBlockEnd.gif            }

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

InBlock.gif            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//如果有异常发生,Dispose()方法放在这里也结束不了Excel进程
InBlock.gif
//                this.Dispose();
InBlock.gif
InBlock.gif                
//如果发生异常,在这里也可以结束Excel进程
InBlock.gif
//                this.KillExcelProcess();
ExpandedSubBlockEnd.gif
            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 另存为Excel文件
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <param name="savePath">保存路径</param>

InBlock.gif        public void SaveAsExcelFile(string savePath)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            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);
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 结束Excel进程
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public void KillExcelProcess()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Process[] myProcesses;
InBlock.gif            DateTime startTime;
InBlock.gif            myProcesses 
= Process.GetProcessesByName("Excel");
InBlock.gif
InBlock.gif            
//得不到Excel进程ID,暂时只能判断进程启动时间
InBlock.gif
            foreach(Process myProcess in myProcesses)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                startTime 
= myProcess.StartTime;
InBlock.gif
InBlock.gif                
if(startTime > beforeTime && startTime < afterTime)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    myProcess.Kill();
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

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

InBlock.gif        public void Dispose()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            wb.Close(
null,null,null);
InBlock.gif            app.Workbooks.Close();
InBlock.gif            app.Quit();
InBlock.gif
InBlock.gif            
//注意:这里用到的所有Excel对象都要执行这个操作,否则结束不了Excel进程
InBlock.gif
            if(rng != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Runtime.InteropServices.Marshal.ReleaseComObject(rng);
InBlock.gif                rng 
= null;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
if(tb != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Runtime.InteropServices.Marshal.ReleaseComObject(tb);
InBlock.gif                tb 
= null;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
if(ws != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
InBlock.gif                ws 
= null;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
if(wb != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Runtime.InteropServices.Marshal.ReleaseComObject(wb);
InBlock.gif                wb 
= null;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
if(app != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
InBlock.gif                app 
= null;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            GC.Collect();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

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

点这里下载ExcelTest.rar

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值