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

C#中通过com组件操作excel不能关闭的问题

2014-07-16 21:25 477 查看
问题:

当用如下代码操作完Excel,虽然调用了Application的Quit()方法,但发现Excel进程并没退出。

object missing = System.Reflection.Missing .Value;
Application app = new Application();
app.Visible = false ;
app.UserControl = true ;
Workbook wb = app.Workbooks.Open(path, missing, true , missing, missing, missing, missing,
missing, missing, true , missing, missing, missing, missing, missing);
Worksheet ws = (Worksheet )wb.Worksheets.get_Item(1);
Console .WriteLine(ws.Cells[2,1].Value);
ws.Close();
ws = null;
app.Quit();
app = null;


结果:



[align=left]原因:[/align]
When Visual Studio .NET calls a COM object from managed code, it automatically creates a Runtime Callable Wrapper (RCW). The RCW marshals calls between the .NET application and the COM object. The RCW keeps a reference count on the COM object.
Therefore, if all references have not been released on the RCW, the COM object does not quit.

[align=left]解决方案:[/align]

[align=left]1、为每一个对象定义一个变量。[/align]
[align=left]例如:[/align]
[align=left]把这段代码[/align]

[align=left]Workbook wb = wbs.Open(path, missing, true , missing, missing, missing, missing,[/align]
[align=left] missing, missing, true , missing, missing, missing, missing, missing);[/align]
改为
Workbooks wbs = app.Workbooks;
[align=left]Workbook wb = wbs.Open(path, missing, true , missing, missing, missing, missing,[/align]
[align=left] missing, missing, true , missing, missing, missing, missing, missing);[/align]

[align=left]2、当使用完com对象对其循环调用System.Runtime.InteropServices.Marshal.ReleaseComObject 直到返回值为0[/align]
[align=left]3、设置变量位null[/align]
[align=left]4、调用Quit方法通知服务器关闭[/align]
[align=left]5、调用GC .Collect();[/align]

[align=left]最终:[/align]
[align=left]把上边的代码修改为:[/align]

public static void ExcelRead(string path)
{

object missing = System.Reflection.Missing.Value;
Application app = new Application();
app.Visible = false;
app.UserControl = true;
Workbooks wbs = app.Workbooks;
Workbook wb = wbs.Open(path, missing, true, missing, missing, missing, missing,
missing, missing, true, missing, missing, missing, missing, missing);
Sheets wss = wb.Worksheets;
Worksheet ws = (Worksheet)wss.get_Item(1);
Console.WriteLine(ws.Cells[2,1].Value);
NAR(ws);
ws = null;
NAR(wss);
wss = null;
wb.Close();
NAR(wb);
wb = null;
wbs.Close();
NAR(wbs);
wbs = null;
app.Quit();
NAR(app);
app = null;
GC.Collect();
}
private static void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;

}
catch
{ }
finally
{
o = null;
}
}
结果能正常关闭Excel进程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: