我创建了一个excel加载项,用于处理活动工作表并打开另一个excel应用程序并写入另一个工作表。程序完成后我不想关闭excel,因为这取决于用户。当我的程序运行时,我可以在任务管理器中看到EXCEL.exe,当它完成后,我仍然可以看到它,这就是我的期望,当我关闭EXCEL时,它会消失,但我仍然不知道是否我应该调用ReleaseComObject
以及调用它的变量和时间。这是我目前的代码:
public class ProcessExcel {
Worksheet activeSheet;
ProcessExcel_Click(object sender, EventArgs e)
{
//Do I need to break these into variables and/or do I need to dispose of them?
var addIn = Globals.ThisAddIn;
var application = addIn.Application;
var workbook = application.ActiveWorkbook;
activeSheet = workbook.ActiveSheet;
var processor= new Processor(activeSheet, _bank);
var processedCells = processor.Process();
CreateExcelFile();
GenerateOutput(processor, processedCells);
}
private void CreateExcelFile()
{
var xlApp = new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
MessageBox.Show("EXCEL could not be started");
return;
}
xlApp.Visible = true;
var workbooks = xlApp.Workbooks;
var wb = workbooks.Add();
xlApp.DefaultSaveFormat = xlFileFormat;
var worksheets = wb.Worksheets;
activeSheet = worksheets.Add();
activeSheet.Name = "Output";
if (activeSheet == null)
{
MessageBox.Show("Worksheet could not be created");
return;
}
var outputSheetColumns = activeSheet.Columns;
foreach (var item in data.Columns)
{
if (item.TargetDataType != null)
{
if (item.TargetDataType.ToLower() == DataType.Text.ToLower())
{
outputSheetColumns[item.TargetColumnNumber].Numberformat = NumberFormat.Text;
}
}
}
}
private void GenerateOutput(Processor processor, ProcessedCells processedCells)
{
var cells = activeSheet.Cells;
if (data.IncludeHeader)
{
processor.SetHeaders(activeSheet);
}
foreach (var cell in processedCells.ValidCells)
{
var currentCell = cells[cell.RowNumber, cell.ColumnNumber];
currentCell.Value2 = cell.Value;
}
}
}
从上面可以看出,我正在尝试(我认为)使用所有com对象的变量并避免两个点。我确实有以下方法进行清理,但不确定使用它的对象以及何时:
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
我看到ReleaseComObject
可能没有必要,我可以致电:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
如果用户负责关闭excel应用程序,上述是否必要?
答案 0 :(得分:0)
不幸的是,一个有效的解决方案就是杀死进程
System.Diagnostics.Process pro = ExcelProcess.GetExcelProcess(ExcelApp);
pro.Kill();
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
public static System.Diagnostics.Process GetExcelProcess(oExcel.Application excelApp)
{
int id;
GetWindowThreadProcessId(excelApp.Hwnd, out id);
return System.Diagnostics.Process.GetProcessById(id);
}
答案 1 :(得分:0)
使用内置于interop中的函数退出Workbook对象。
using Excel = Microsoft.Office.Interop.Excel; // skip a lot of redundant typing
// declare application/workbook/worksheet objects
Excel.Application applicationObject = new Excel.Application();
Excel.Workbook workbookObject;
Excel.Worksheet worksheetObject;
workbookObject = applicationObject.Open(/* lot of parameters go here */);
worksheetObject = workbookObject.Sheets["SheetName"];
DoThings(worksheetObject);
// finished working with sheet, time to close it
workbookObject.SaveAs(/* necessary parameters */);
workbookObject.Close(/* necessary parameters */);
调用Workbook.Close()方法后,它将结束您通过打开
创建的进程