您的位置:首页 > 编程语言 > ASP

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

2009-05-06 15:46 821 查看

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

posted on 2005年11月19日 22:45 由 wellwell
毕设是碰到这个问题,一直是手动关闭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






{




/**////


/// Excel的摘要说明。


///


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();


}


}






/**////


/// 另存为Excel文件


///


/// 保存路径


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);


}






/**////


/// 结束Excel进程


///


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();


}


}


}






/**////


/// 如果对Excel的操作没有引发异常的话,用这个方法可以正常结束Excel进程


/// 否则要用KillExcelProcess()方法来结束Excel进程


///


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方法强行结束。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐