我正在上传一个excel文件,打开它,阅读内容,然后关闭并删除它。
一切正常,但是我注意到“ Microsoft Excel”进程仍在任务管理器中后台运行。
我已经尝试过搜索并且尝试了不同的答案,但是没有一个对我有用。有人有什么想法吗?
我正在尝试关闭应用程序,释放com但没有运气的不同方式。
我正在使用的代码:
public ActionResult UploadUpdateOOBList()
{
CheckPermissions("UpdateOOBList");
string[] typesallowed = new string[] { ".xls", ".xlsx" };
HttpPostedFileBase file = Request.Files[0];
var fname = file.FileName;
if (!typesallowed.Any(fname.Contains))
{
return Json("NotAllowed");
}
file.SaveAs(Server.MapPath("~/Uploads/OOB List/") + fname);
//Create COM Objects. Create a COM object for everything that is referenced
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbooks xlWorkbooks = xlApp.Workbooks;
Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlWorkbooks.Open(Server.MapPath("~/Uploads/OOB List/") + fname);
Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[2];
Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
//Create empty OOB data list
List<OOBList.OOBDetails> oob_data = new List<OOBList.OOBDetails>();
int rowcount = xlRange.Rows.Count;
for (int down = 4; down <= rowcount; down++)
{
//Make sure first column isn't null
if( xlRange.Cells[down, 1] != null && xlRange.Cells[down, 1].Value2 != null )
{
string siteno = xlRange.Cells[down, 1].Value2.ToString();
string sitename = xlRange.Cells[down, 2].Value2.ToString();
string description = xlRange.Cells[down, 4].Value2.ToString();
string cabinoob = xlRange.Cells[down, 5].Value2.ToString();
string toweroob = xlRange.Cells[down, 6].Value2.ToString();
string manageoob = xlRange.Cells[down, 7].Value2.ToString();
string resolutiondate = xlRange.Cells[down, 8].Value2.ToString();
var resolutiondate_converted = DateTime.FromOADate(Convert.ToDouble(resolutiondate)).ToString("dd/MM/yyyy");
oob_data.Add(new OOBList.OOBDetails
{
SiteNo = siteno,
SiteName = sitename,
Description = description,
CabinOOB = cabinoob,
TowerOOB = toweroob,
ManageOOB = manageoob,
TargetResolutionDate = resolutiondate_converted
});
Debug.Write("Adding SiteNo: " + siteno);
}
}
//HERE IS THE PROBLEM, DOESNT SEEM TO CLOSE THE PROCESS.
xlWorkbook.Close();
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbooks);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorksheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
xlWorkbook = null;
xlWorkbooks = null;
xlWorksheet = null;
xlRange = null;
xlApp = null;
GC.Collect();
//Now delete file.
System.IO.File.Delete(Server.MapPath("~/Uploads/OOB List/") + fname);
var nowdate = DateTime.Now.ToString("dd/MM/yyyy");
System.IO.File.WriteAllText(Server.MapPath("~/Uploads/OOB List/lastupdated.txt"),nowdate);
return Json("Success");
}
答案 0 :(得分:0)
在某处发现:“自动化服务器通过RegisterActiveObject()API在运行对象表(ROT)中进行注册。
注意:如果有多个自动化服务器实例同时运行,则GetActiveObject()API函数将IDispatch指针返回到首次运行的实例。
从理论上讲,您可以为每个单独的实例迭代ROT,但是如果ROT中已经存在另一个实例,则Office应用程序不会自行注册,因为其别名始终相同,并且无法区分。这意味着除了第一个实例外,您无法附加到任何实例。但是,由于Office应用程序也在ROT中注册其文档,因此您可以通过迭代ROT查找特定文档,附加到此文档并从该文档中获取Application对象,来成功附加到其他实例。有关迭代ROT和查找文档名称的代码示例,请单击下面的文章编号,以查看Microsoft知识库中相应的文章:190985如何从OCX获取Excel或Word文档的IDispatch”。
希望这是一个提示-希望我比...早知道...
答案 1 :(得分:0)
以下代码根据nabuchodonossor的评论解决了我的问题:
//Create don't kill processes
var dontkill = new List<Process>();
Process[] procs = Process.GetProcessesByName("EXCEL");
foreach (Process p in procs)
{
dontkill.Add(p);
}
//EXCEL CODE HERE.
xlWorkbook.Close();
xlApp.Quit();
//Now kill only the created process above.
procs = Process.GetProcessesByName("EXCEL");
foreach (Process p in procs)
{
if( !dontkill.Contains(p))
{
p.Kill();
}
}
Marshal.FinalReleaseComObject(xlApp);
答案 2 :(得分:0)
使用Excel Interop库时,我使用以下代码打开和关闭文档:
Application xlApp = null;
Workbook xlWorkbook = null;
_Worksheet xlWorksheet = null;
Range xlRange = null;
try
{
xlApp = new Application();
xlWorkbook = xlApp.Workbooks.Open(filename);
xlWorksheet = xlWorkbook.Sheets[1];
xlRange = xlWorksheet.UsedRange;
// Do stuff with excel data
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
//release com objects to fully kill excel process from running in the background
if (xlRange != null)
{
Marshal.ReleaseComObject(xlRange);
}
if (xlWorksheet != null)
{
Marshal.ReleaseComObject(xlWorksheet);
}
//close and release
if (xlWorkbook != null)
{
xlWorkbook.Close();
Marshal.ReleaseComObject(xlWorkbook);
}
//quit and release
if (xlApp != null)
{
xlApp.Quit();
Marshal.ReleaseComObject(xlApp);
}
}
答案 3 :(得分:0)
给大家另一个提示,我决定使用ClosedXML。
Interop Excel大约需要30秒才能读取750行。
然后,ClosedXML花了3秒的时间用以下代码完成相同的操作,该代码也不会留下任何讨厌的进程:
//Create empty OOB data list
List<OOBList.OOBDetails> oob_data = new List<OOBList.OOBDetails>();
string fileName = Server.MapPath("~/Uploads/OOB List/") + fname;
using (var excelWorkbook = new XLWorkbook(fileName))
{
var nonEmptyDataRows = excelWorkbook.Worksheet(2).RowsUsed();
foreach (var dataRow in nonEmptyDataRows)
{
//for row number check
if (dataRow.RowNumber() >= 4 )
{
string siteno = dataRow.Cell(1).GetValue<string>();
string sitename = dataRow.Cell(2).GetValue<string>();
string description = dataRow.Cell(4).GetValue<string>();
string cabinoob = dataRow.Cell(5).GetValue<string>();
string toweroob = dataRow.Cell(6).GetValue<string>();
string manageoob = dataRow.Cell(7).GetValue<string>();
string resolutiondate = dataRow.Cell(8).GetValue<string>();
string resolutiondate_converted = resolutiondate.Substring(resolutiondate.Length - 9);
oob_data.Add(new OOBList.OOBDetails
{
SiteNo = siteno,
SiteName = sitename,
Description = description,
CabinOOB = cabinoob,
TowerOOB = toweroob,
ManageOOB = manageoob,
TargetResolutionDate = resolutiondate_converted
});
Debug.Write("Adding SiteNo: " + siteno + "\n");
}
}
}