I'm developing c# excel VSTO project solution. I have a excelutil class like the following:
public class ExcelUtil : IDisposable
{
/// <summary>Excel Application</summary>
private Excel.Application xlApp = null;
/// <summary>Excel Book</summary>
private Excel.Workbook xlBook = null;
/// <summary>Excel Sheets</summary>
private Excel.Sheets xlSheets = null;
/// <summary>Excel Worksheet</summary>
private Excel.Worksheet xlWorksheet = null;
/// <summary>Sheet Name List</summary>
private List<string> mSheetNameList = null;
/// <summary>
/// Sheet Name List
/// </summary>
public List<string> SheetNameList
{
get
{
if (mSheetNameList == null)
{
mSheetNameList = new List<string>();
foreach (Excel.Worksheet sheet in xlSheets)
{
mSheetNameList.Add(sheet.Name);
}
}
return mSheetNameList;
}
}
public ExcelUtil()
{
xlApp = Globals.ThisAddIn.Application;
xlBook = xlApp.ActiveWorkbook;
xlSheets = xlBook.Sheets;
}
public void SetWorkSheet(string sheetName)
{
xlWorksheet = xlSheets[sheetName];
}
public void SetTextForRange(string range, string text)
{
Excel.Range xrange = xlWorksheet.get_Range(range);
xrange.Value2 = text;
xlBook.Save();
}
public void Dispose()
{
releaseObject(xlApp);
releaseObject(xlBook);
releaseObject(xlSheets);
releaseObject(xlWorksheet);
}
private void releaseObject(object obj)
{
if (obj == null)
{
return;
}
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();
}
}
}
In Add-In project, I add a Windows Forms
in it. In the Ribbon, I have a button and it will show the Form
when click the button.
public partial class Ribbon1
{
private void button2_Click(object sender, RibbonControlEventArgs e)
{
Form2 form = new Form2();
form.Show();
}
}
In the Form2
, there's a button. When clicking the button, I will call the excelUtil's method to do some operations for the worksheet.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ExcelUtil excelUtil = new ExcelUtil();
var sheetNames = excelUtil.SheetNameList;
excelUtil.SetWorkSheet(sheetNames.FirstOrDefault());
excelUtil.SetTextForRange("A1", "hello.");
excelUtil.Dispose();
}
}
At the first time, it worked well. But if I close the Form2
and open it again, when I click the button, it throws System. Runtime. Interopservices. Invalidcomobjectexception: 'COM objects separated from the underlying RCW cannot be used.
So, I do not know when it's appropriate to relase the excel COM objects.