Reputation: 1966
Everytime I run this code, the object won't close. I still have an excel.exe running in the task manager. Even if I set the objects = null, still nothing. I've even tried using the objects .Quit() method.
What am I doing wrong here?
private bool ValidateQM()
{
//setup the objects
Excel.Application oXL = null;
Excel.Workbook oWB = null;
Excel.Worksheet oSheet = null;
int hWnd = 0;
try
{
//Start Excel and get Application object.
oXL = new Excel.Application();
hWnd = oXL.Application.Hwnd;
oXL.Visible = false;
//Open the workbook.
oWB = oXL.Workbooks.Open(workingForm, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",true, false, 0, true, false, false);
//Get the Worksheet
oSheet = oWB.Worksheets[1];
//Check the date values
string mydatetime = oSheet.Cells[5, 33].Text.ToString() + " " + oSheet.Cells[7, 33].Text.ToString();
string dateofscore = oSheet.Cells[3, 12].Text.ToString();
DateTime.Parse(mydatetime); //make my string a real boy
DateTime.Parse(dateofscore);
// Cleanup
GC.Collect();
GC.WaitForPendingFinalizers();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSheet);
//oWB.Close();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWB);
//oXL.Quit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oXL);
return true;
}
Upvotes: 2
Views: 790
Reputation: 11230
When you call GC.Collect(), the oXL and oWB objects are still in scope so there's a reference active to them. As a result, GC.Collect() won't touch them. If you want to ensure they are garbage collected, set them to null so there's no references active when GC.Collect() is called. Also, you may want to call Close() on the active workbook and Quit() on the Excel application. You could also put everything in its own scope with braces { } so that it all went out of scope together.
// Cleanup
oWB.Close(false);
oWB = null;
oXL.Quit();
oXL = null;
hWnd = null;
#if (DEBUG_SPEED_UP_GC)
GC.Collect();
GC.WaitForPendingFinalizers();
#endif
Edit: Note that manually calling garbage collection is a bad idea. I am assuming you are only doing this for debugging purposes to speed up when the GC occurs, so I added the #if.
Upvotes: 1
Reputation: 2371
Aren't you falling foul of the "don't use 2 dots" rule in the line hWnd = oXL.Application.Hwnd
? See Excel interop libraries incompatible with ASP.NET? for more on this.
Upvotes: 1
Reputation: 27214
I'm going to assume that an exception is not thrown and the catch
handler that you're not showing doesn't do anything malign for the purposes of your problem.
I've even tried using the object's
Quit
method
Unless there's some documented advice against this, I don't see why you wouldn't always call Quit
to indicate you have finished with the application.
//Start Excel and get Application object. oXL = new
Excel.Application();
hWnd = oXL.Application.Hwnd;
oXL.Visible = false;
Nevermind that you're changing the visibility of a window you don't own, what happens if Excel displays a warning while quitting? Setting Visible
to false
on the parent window will obscure it from the user.
For the purposes of debugging, try not hiding the window.
There's some information here on what you can do to prevent Excel from producing warnings that would otherwise require interactive attention. The basic gist of it:
DisplayAlerts = false
AskToUpdateLinks = false
AlertBeforeOverwriting = false
Interactive = false
Visible = false
FeatureInstall = 0 'msoFeatureInstallNone
You are running your application inside an interactive user session, right? Because anything else is not supported:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
Upvotes: 0