我一直在努力解决这个问题几天,我已经进行了研究并应用了我在各种论坛上发现的所有建议,但我仍然无法解决。
我的问题是excel使用互操作库,我有一个excel文件用作模板,所以我打开它并保存在一个新名称的新位置。除了在创建和关闭文件后Excel进程继续运行外,一切都很有效。
这是我的代码
protected string CreateExcel(string strProjectID, string strFileMapPath)
{
string strCurrentDir = HttpContext.Current.Server.MapPath("~/Reports/Templates/");
string strFile = "Not_Created";
Application oXL;
Workbook oWB;
oXL = new Application();
oXL.Visible = false;
Workbooks wbks = oXL.Workbooks;
//opening template file
oWB = wbks.Open(strFileMapPath);
oXL.Visible = false;
oXL.UserControl = false;
strFile = strProjectID + "_" + DateTime.Now.Ticks.ToString() + ".xlsx";
//Saving file with new name
oWB.SaveAs(strCurrentDir + strFile, XlFileFormat.xlWorkbookDefault, null, null, false, false, XlSaveAsAccessMode.xlExclusive, false, false, null, null);
oWB.Close(false, strCurrentDir + strFile, Type.Missing);
wbks.Close();
oXL.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbks);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB);
oWB = null;
oXL = null;
wbks = null;
GC.Collect();
return strFile;
}
如您所见,我正在关闭并释放所有对象,但应用程序不会退出。
我正在使用IIS7在32位的Windows Server 2008(生产)和Windows 7(开发)中进行测试。
答案 0 :(得分:6)
尝试
Process excelProcess = Process.GetProcessesByName("EXCEL")[0];
if (!excelProcess.CloseMainWindow())
{
excelProcess.Kill();
}
答案 1 :(得分:3)
这就是我解决这个问题的方法:
// Store the Excel processes before opening.
Process[] processesBefore = Process.GetProcessesByName("excel");
// Open the file in Excel.
Application excelApplication = new Application();
Workbook excelWorkbook = excelApplication.Workbooks.Open(Filename);
// Get Excel processes after opening the file.
Process[] processesAfter = Process.GetProcessesByName("excel");
// Now find the process id that was created, and store it.
int processID = 0;
foreach (Process process in processesAfter)
{
if (!processesBefore.Select(p => p.Id).Contains(process.Id))
{
processID = process.Id;
}
}
// Do the Excel stuff
// Now close the file with the COM object.
excelWorkbook.Close();
excelApplication.Workbooks.Close();
excelApplication.Quit();
// And now kill the process.
if (processID != 0)
{
Process process = Process.GetProcessById(processID);
process.Kill();
}
答案 2 :(得分:1)
我为它创建了这个方法,在我的测试中它可以工作。
private void ClearMemory(Application excelApp) {
excelApp.DisplayAlerts = false;
excelApp.ActiveWorkbook.Close(0);
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
}
答案 3 :(得分:0)
尝试使用Open XML SDK 2.0 for Microsoft Office library创建excel文档,而不是使用互操作程序集。它的运行速度更快,而且使用起来更容易。
答案 4 :(得分:0)
这是VB版本 - 我有一个大型项目使用它而不是时间转换为更好的系统,所以这里是相同的答案...在vb.NET中
使用此方法获取进程ID(在打开Excel工作表之前)
Dim excelProcess(0) As Process
excelProcess = Process.GetProcessesByName("excel")
完成工作表后:
xlWorkBook.Close(SaveChanges:=False)
xlApp.Workbooks.Close()
xlApp.Quit()
'Kill the process
If Not excelProcess(0).CloseMainWindow() Then
excelProcess(0).Kill()
End If
答案 5 :(得分:0)
看看这里:How can I get the ProcessID (PID) for a hidden Excel Application instance
您可以通过GetWindowThreadProcessId
API跟踪您的ProcessID,然后杀死与您的Excel应用对象实例特别匹配的流程。
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
Process GetExcelProcess(Microsoft.Office.Interop.Excel.Application excelApp)
{
int id;
GetWindowThreadProcessId(excelApp.Hwnd, out id);
return Process.GetProcessById(id);
}
void TerminateExcelProcess(Microsoft.Office.Interop.Excel.Application excelApp)
{
var process = GetExcelProcess(excelApp);
if (process != null)
{
process.Kill();
}
}
答案 6 :(得分:0)
答案 7 :(得分:-1)
oWB.Close(false, strCurrentDir + strFile, Type.Missing);
oWB.Dispose();
wbks.Close();
wbks.Dispose();
oXL.Quit();
oXL.Dispose();
System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wbks);
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB);