Same killing Excel problems

wakemaster

Member
Joined
Aug 19, 2003
Messages
5
Location
Sweden
I have read and tried all solutions in this forum and the only one that works is the killExcelPr posted by Melegant and is:

Private Sub KillExcelPr()
Dim mp As Process() = Procss.GetProcessesByName("EXCEL")

Dim p As Process
For Each P In mp
If P.Responding Then
If p.MainWindowTitle = "" Then
p.Kill()
End If
Else
p.Kill()
End If
Next p
End Sub

This works but isn
 
try this msdn link to a download for the PIAs ...
msdn download link

then when downloaded , theres a batch file to register the COM dlls.
then you need to do this...
  • Dont choose the default Excel library, but click the " Browse " button...
  • Browse to the location of the PIAs and you will see the following... " Microsoft.Office.Interop.Excel.dll "
  • Select that as the reference, then do the following code ( using a path to an Excel file )...

Code:
        Dim objXl As New Microsoft.Office.Interop.Excel.Application()
        Dim objBook As Microsoft.Office.Interop.Excel.Workbook = objXl.Workbooks.Open("C:\Book1.xls")
        Dim objSheet As Microsoft.Office.Interop.Excel.Worksheet = objBook.Worksheets("Sheet1")

        MessageBox.Show(objSheet.UsedRange.Count)
        /// do any stuff here to read / write to the excel book.
        objXl.Quit()
try that and see if it helps :)
 
A very delayed response, but...

Hi,

Ive been doing a lot of stuff with Excel and .NET and have run into this process not dying problem in the past. The best way Ive found to combat it is this:

After doing all your cleanup of Excel objects, make sure you call the Quit method on the Excel Application object. Then, for good measure, set the variable you are using to reference Excel to nothing, and finally on the very next line call GC.Collect() to force garbage collection. Ive found this to solve this annoying problem of Excel processes stacking up and never going away, even when your application ends.

I also, for good measure although it may not really be required, make sure I keep track of every single object reference and set all of those to nothing when I am finished, a holdover from when I used VB 6 to access Excel and would get the exact same problem if even one stray variable was still referencing an object in Excel.

I hope this helps anyone who might stumble onto it while looking for something else like I did.
 
I found this on the net and it has worked effectively for me..

close the workbook object
close the excel applications workbook object(eg: excapp.workbooks.close())
quit excel application

release all the objects connected to excel(the application, workbook, worksheet, range, etc) by using the following command;

System.Runtime.InteropServices.Marshal.ReleaseComObject(ObjectName)
set all the objects to nothing
do a garbage collect

Regarding PIAs, it seems to work for office xp and above, if u r running 2000 or below then they dont work, I found that out the hard way, I installed PIA on office 2000 and now wherever there is a call to an Office application I get an "invalid cast exception:query interface for excel/Word failed", If any of u know how to remedy this let me know....
 
Excel killing problems

Open this comes up in the right spot... replied before signing in... if not mod please move appropriately...

Tonight I had to do something that required exporting to Excel and quickly discovered this Office killing problem... the fix mentioned in the link (http://support.microsoft.com/?kbid=317109) referances PIAs or something like that for Office XP... but our company wont go XP in the near future, nor do I plan to... hate bubbly crap... anyway... there is code in there that is important and is the key to killing on Office 2000... the Marshal.ReleaseObject blah blah blah....

the following is my code I use on Excel 2000 and the task mangager drops the Excel thread just as it should... keep in mind that I actually do all my Excel operations in a seperate class that I have a Dispose method for that I call from the form that uses it...

C#:
                ExcelApp.Quit();			System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp);
	ExcelApp = null;
	GC.Collect();

Closing workbooks and anything like that you do before here... common sense... you should know that... those are the main things above you need... also pay attention to how Microsoft tells you to delclare your variables on the link above... tonight this has worked for me... we will see when I make Excel stay open longer because Im doing the complex stuff of my program.

Hope this helps someone.
 
I decided I should post this class, this has simple functions you commonly use when exporting into Excel... this was my first draft, I have since modified it, but this is the basic one that will get you started if you are having trouble understanding how to use Excel and have it close without remaining in your task-manager:

C#:
using System;
namespace Microsoft.ExpOffice02
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	public class ExportExcel : IDisposable
	{
		private Excel.ApplicationClass ExcelApp = null;
		private Excel.Workbooks myWorkbooks = null;
		private Excel.Workbook myWorkbook = null;
		private Excel.Worksheet myWorksheet = null;
		// Track whether Dispose has been called.
		private bool disposed = false;
		public ExportExcel()
		{
			//no initialization as of yet...
			ExcelApp = new Excel.ApplicationClass();
			myWorkbooks = ExcelApp.Workbooks;
			myWorkbook = myWorkbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet);
			myWorksheet = (Excel.Worksheet) ExcelApp.ActiveSheet;
		}
		// Implement IDisposable.
		// Do not make this method virtual.
		// A derived class should not be able to override this method.
		private void ComDestroy(object o)
		{
			try
			{
				System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
			}
			catch {}
			finally
			{
				o = null;
			}
		}
		public void Dispose()
		{
			Dispose(true);
			// This object will be cleaned up by the Dispose method.
			// Therefore, you should call GC.SupressFinalize to
			// take this object off the finalization queue 
			// and prevent finalization code for this object
			// from executing a second time.
			GC.SuppressFinalize(this);
		}

		// Dispose(bool disposing) executes in two distinct scenarios.
		// If disposing equals true, the method has been called directly
		// or indirectly by a users code. Managed and unmanaged resources
		// can be disposed.
		// If disposing equals false, the method has been called by the 
		// runtime from inside the finalizer and you should not reference 
		// other objects. Only unmanaged resources can be disposed.
		private void Dispose(bool disposing)
		{
			// Check to see if Dispose has already been called.
			if(!this.disposed)
			{
				// If disposing equals true, dispose all managed 
				// and unmanaged resources.
				if(disposing)
				{
					// Dispose managed resources.
				}
				// Call the appropriate methods to clean up 
				// unmanaged resources here.
				// If disposing is false, 
				// only the following code is executed
				ComDestroy(myWorksheet);

				myWorkbook.Close(false, null, null);
				ComDestroy(myWorkbook);

				myWorkbooks.Close();
				ComDestroy(myWorkbooks);

				ExcelApp.Quit();
				ComDestroy(ExcelApp);
				GC.Collect();
			}
			disposed = true;         
		}
		// Use C# destructor syntax for finalization code.
		// This destructor will run only if the Dispose method 
		// does not get called.
		// It gives your base class the opportunity to finalize.
		// Do not provide destructors in types derived from this class.
		~ExportExcel()      
		{
			// Do not re-create Dispose clean-up code here.
			// Calling Dispose(false) is optimal in terms of
			// readability and maintainability.
			Dispose(false);
		}
		public void Show()
		{
			ExcelApp.Visible = true;
		}
		public void Hide()
		{
			ExcelApp.Visible = false;
		}
		public void WriteCell(int row, int column, string val)
		{
			WriteCell(row, column, val, false, false, false);
		}
		public void WriteCell(int row, int column, string val, bool bold, bool underline, bool italic)
		{
			/* It doesnt look like this would be right, but you actually AREE
			 * selecting the cell of the cells... it all gets into how you call
			 * things and keep from building up threads... you could directly
			 * call myWorksheet.Cells[1, 1]="SomeValue"; but this would result
			 * in an instance of EXCEL.EXE remaining in the task manager because
			 * you are orphaning two instances of Excel.Range, the first being the
			 * myWorksheet.Cells, the second becing the [1, 1] which is a range
			 * of its own... weird I know, but this is by Microsoft design and
			 * if you want to keep your thread clean, do it this way! */

			//Rows and Columns are Base 1;
			if(row < 1 || column < 1)
				throw new System.ArgumentOutOfRangeException("Row/Column", "Row or Column must be 1 or greater!");
			Excel.Range myCells = (Excel.Range) myWorksheet.Cells;
			Excel.Range myCell = (Excel.Range) myCells[row, column];
			Excel.Font myCellFont = myCell.Font;
			
			myCellFont.Bold = bold;
			myCellFont.Underline = underline;
			myCellFont.Italic = italic;

			myCell.Value = val;

			ComDestroy(myCellFont);
			ComDestroy(myCell);
			ComDestroy(myCells);
		}
		public void AutoFitColumn(int column)
		{
			if(column < 1)
				throw new System.ArgumentOutOfRangeException("Column", "Column must be 1 or greater!");
			Excel.Range myCells = (Excel.Range) myWorksheet.Cells;
			Excel.Range myCell = (Excel.Range) myCells[1, column];
			Excel.Range myColumn = (Excel.Range) myCell.EntireColumn;

			myColumn.AutoFit();
			
			ComDestroy(myColumn);
			ComDestroy(myCell);
			ComDestroy(myCells);
		}
		public void Save(string path, bool overwrite)
		{
			bool exists = System.IO.File.Exists(path);
			if(exists==true && overwrite==false)
			{
				throw new System.IO.IOException("A file already exists under the given name and overwrite is set to false, unable to save!");
			}
			if(exists==true && overwrite==true)
			{
				System.IO.File.Delete(path);
			}
			myWorkbook.SaveAs(path, Excel.XlFileFormat.xlWorkbookNormal, "", "", false, false, Excel.XlSaveAsAccessMode.xlNoChange, Excel.XlSaveConflictResolution.xlLocalSessionChanges, false, null, null);
		}
	}
}

Hope that helps some people :)
 
Back
Top