Connecting Tech Pros Worldwide Forums | Help | Site Map

Excel application.quit leaves instance of Excel running

ChrisBowringGG@gmail.com
Guest
 
Posts: n/a
#1: Nov 17 '05
When you use Application.Quit() on an Excel application,
there can still be an instance of Excel running,
as seen in Task Manager.

You can try following the advice on MSDN:

http://support.microsoft.com/kb/Q317109

but this didn't solve the problem for me.

Instead, I used a crow-bar and did the following:

foreach (Process process in Process.GetProcessesByName("Excel")) {
process.Kill();
}

Process belongs to System.Diagnostics.




Christof Nordiek
Guest
 
Posts: n/a
#2: Nov 17 '05

re: Excel application.quit leaves instance of Excel running


See Inline
<ChrisBowringGG@gmail.com> schrieb im Newsbeitrag
news:1127211606.853485.178180@g49g2000cwa.googlegr oups.com...[color=blue]
> When you use Application.Quit() on an Excel application,
> there can still be an instance of Excel running,
> as seen in Task Manager.
>
> You can try following the advice on MSDN:
>
> http://support.microsoft.com/kb/Q317109
>
> but this didn't solve the problem for me.[/color]

It works, but you have to call ReleaseComObject on every!!! excel object
your referencing.
Even on collection.
So instead of
Excel.Workbook workbook = oApp.Workbooks[0]:

you've got to use
Excel.Workbooks workbooks = oApp.Workbooks;
Excel Workbook workbook = workbooks[0];

And then call ReleaseCommObject on workbooks as well.
[color=blue]
>
> Instead, I used a crow-bar and did the following:
>
> foreach (Process process in Process.GetProcessesByName("Excel")) {
> process.Kill();
> }
>[/color]
That's Dangerous.
You can't be sure the user is not running another Excel-session.

Christof


ChrisBowringGG@gmail.com
Guest
 
Posts: n/a
#3: Nov 17 '05

re: Excel application.quit leaves instance of Excel running


Christof,

could you explain why the following code doesn't kill the Excel
process:

Application application = new ApplicationClass();

try {
Workbooks books = application.Workbooks;
Workbook book = books.Open(BookPath, false, true,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);

application.DisplayAlerts = false;

XmlMaps maps = book.XmlMaps;
XmlMap dataMap = maps["Data_Map"];
dataMap.ImportXml(document.OuterXml, (object)true);
application.Calculate();
XmlMap outputMap = maps["Output_Map"];
outputMap.Export(outputPath, true);

Marshal.ReleaseComObject(outputMap);
outputMap = null;

Marshal.ReleaseComObject(dataMap);
dataMap = null;

Marshal.ReleaseComObject(maps);
maps = null;

Marshal.ReleaseComObject(book);
book = null;

Marshal.ReleaseComObject(books);
books = null;
}
finally {
application.Quit();
Marshal.ReleaseComObject(application);
application = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}

I can't see any objects I've referenced that I haven't released.

Thanks,

Chris.

Christof Nordiek wrote:[color=blue]
> See Inline
> <ChrisBowringGG@gmail.com> schrieb im Newsbeitrag
> news:1127211606.853485.178180@g49g2000cwa.googlegr oups.com...[color=green]
> > When you use Application.Quit() on an Excel application,
> > there can still be an instance of Excel running,
> > as seen in Task Manager.
> >
> > You can try following the advice on MSDN:
> >
> > http://support.microsoft.com/kb/Q317109
> >
> > but this didn't solve the problem for me.[/color]
>
> It works, but you have to call ReleaseComObject on every!!! excel object
> your referencing.
> Even on collection.
> So instead of
> Excel.Workbook workbook = oApp.Workbooks[0]:
>
> you've got to use
> Excel.Workbooks workbooks = oApp.Workbooks;
> Excel Workbook workbook = workbooks[0];
>
> And then call ReleaseCommObject on workbooks as well.
>[color=green]
> >
> > Instead, I used a crow-bar and did the following:
> >
> > foreach (Process process in Process.GetProcessesByName("Excel")) {
> > process.Kill();
> > }
> >[/color]
> That's Dangerous.
> You can't be sure the user is not running another Excel-session.
>
> Christof[/color]

ChrisBowringGG@gmail.com
Guest
 
Posts: n/a
#4: Nov 17 '05

re: Excel application.quit leaves instance of Excel running


By the way, there are no exceptions caught, so all the code in the try
clause runs.

Chris.

Christof Nordiek
Guest
 
Posts: n/a
#5: Nov 17 '05

re: Excel application.quit leaves instance of Excel running


<ChrisBowringGG@gmail.com> schrieb im Newsbeitrag
news:1127224411.528202.226190@g43g2000cwa.googlegr oups.com...[color=blue]
> Christof,
>
> could you explain why the following code doesn't kill the Excel
> process:
>
> Application application = new ApplicationClass();
>
> try {
> Workbooks books = application.Workbooks;
> Workbook book = books.Open(BookPath, false, true,
> Type.Missing, Type.Missing, Type.Missing, Type.Missing,
> Type.Missing, Type.Missing, Type.Missing, Type.Missing,
> Type.Missing, Type.Missing, Type.Missing, Type.Missing);
>
> application.DisplayAlerts = false;
>
> XmlMaps maps = book.XmlMaps;
> XmlMap dataMap = maps["Data_Map"];
> dataMap.ImportXml(document.OuterXml, (object)true);
> application.Calculate();
> XmlMap outputMap = maps["Output_Map"];
> outputMap.Export(outputPath, true);
>
> Marshal.ReleaseComObject(outputMap);
> outputMap = null;
>
> Marshal.ReleaseComObject(dataMap);
> dataMap = null;
>
> Marshal.ReleaseComObject(maps);
> maps = null;
>
> Marshal.ReleaseComObject(book);
> book = null;
>
> Marshal.ReleaseComObject(books);
> books = null;
> }
> finally {
> application.Quit();
> Marshal.ReleaseComObject(application);
> application = null;
> GC.Collect();
> GC.WaitForPendingFinalizers();
> }
>
> I can't see any objects I've referenced that I haven't released.[/color]

I can't see neither.
Maybe there is something strange about the XmlMap or XmlMaps wich I don't
know.
If your sure all ReleaseComObject were called i see know cause why Excel
isn't killed.


ChrisBowringGG@gmail.com
Guest
 
Posts: n/a
#6: Nov 17 '05

re: Excel application.quit leaves instance of Excel running


It is possible to use the Process.Kill method safely if you find all
the Excel processes
just before you create a new one, then find all the processes just
after you create the new one,
and compare them to find the one you've just created.

You could safely kill this one and leave the others unharmed, as long
as a new process isn't started
by the user at the same time as the code, e.g.:

Process[] originalProcesses = Process.GetProcessesByName("Excel");

Application application = new ApplicationClass();

Process[] newProcesses = Process.GetProcessesByName("Excel");

ArrayList list = new ArrayList();
foreach (Process newProcess in newProcesses) {
bool isNew = true;
foreach (Process originalProcess in originalProcesses) {
if (originalProcess.Id == newProcess.Id) {
isNew = false;
break;
}
}
if (isNew) list.Add(newProcess);
}

// Do your stuff

foreach (Process process in list) {
process.Kill();
}

This seems to work.

Ron
Guest
 
Posts: n/a
#7: Nov 17 '05

re: Excel application.quit leaves instance of Excel running


I went through this once. Try closing the workbook first:
book.Close(). In my experience, there is no need to call ReleaseComObject on
every Excel object, but you can play with that and see what works for you.

"ChrisBowringGG@gmail.com" wrote:
[color=blue]
> Christof,
>
> could you explain why the following code doesn't kill the Excel
> process:
>
> Application application = new ApplicationClass();
>
> try {
> Workbooks books = application.Workbooks;
> Workbook book = books.Open(BookPath, false, true,
> Type.Missing, Type.Missing, Type.Missing, Type.Missing,
> Type.Missing, Type.Missing, Type.Missing, Type.Missing,
> Type.Missing, Type.Missing, Type.Missing, Type.Missing);
>
> application.DisplayAlerts = false;
>
> XmlMaps maps = book.XmlMaps;
> XmlMap dataMap = maps["Data_Map"];
> dataMap.ImportXml(document.OuterXml, (object)true);
> application.Calculate();
> XmlMap outputMap = maps["Output_Map"];
> outputMap.Export(outputPath, true);
>
> Marshal.ReleaseComObject(outputMap);
> outputMap = null;
>
> Marshal.ReleaseComObject(dataMap);
> dataMap = null;
>
> Marshal.ReleaseComObject(maps);
> maps = null;
>
> Marshal.ReleaseComObject(book);
> book = null;
>
> Marshal.ReleaseComObject(books);
> books = null;
> }
> finally {
> application.Quit();
> Marshal.ReleaseComObject(application);
> application = null;
> GC.Collect();
> GC.WaitForPendingFinalizers();
> }
>
> I can't see any objects I've referenced that I haven't released.
>
> Thanks,
>
> Chris.
>
> Christof Nordiek wrote:[color=green]
> > See Inline
> > <ChrisBowringGG@gmail.com> schrieb im Newsbeitrag
> > news:1127211606.853485.178180@g49g2000cwa.googlegr oups.com...[color=darkred]
> > > When you use Application.Quit() on an Excel application,
> > > there can still be an instance of Excel running,
> > > as seen in Task Manager.
> > >
> > > You can try following the advice on MSDN:
> > >
> > > http://support.microsoft.com/kb/Q317109
> > >
> > > but this didn't solve the problem for me.[/color]
> >
> > It works, but you have to call ReleaseComObject on every!!! excel object
> > your referencing.
> > Even on collection.
> > So instead of
> > Excel.Workbook workbook = oApp.Workbooks[0]:
> >
> > you've got to use
> > Excel.Workbooks workbooks = oApp.Workbooks;
> > Excel Workbook workbook = workbooks[0];
> >
> > And then call ReleaseCommObject on workbooks as well.
> >[color=darkred]
> > >
> > > Instead, I used a crow-bar and did the following:
> > >
> > > foreach (Process process in Process.GetProcessesByName("Excel")) {
> > > process.Kill();
> > > }
> > >[/color]
> > That's Dangerous.
> > You can't be sure the user is not running another Excel-session.
> >
> > Christof[/color]
>
>[/color]
Christof Nordiek
Guest
 
Posts: n/a
#8: Nov 17 '05

re: Excel application.quit leaves instance of Excel running


<ChrisBowringGG@gmail.com> schrieb im Newsbeitrag
news:1127226701.383951.209260@g44g2000cwa.googlegr oups.com...[color=blue]
> It is possible to use the Process.Kill method safely if you find all
> the Excel processes
> just before you create a new one, then find all the processes just
> after you create the new one,
> and compare them to find the one you've just created.
>
> You could safely kill this one and leave the others unharmed, as long
> as a new process isn't started
> by the user at the same time as the code, e.g.:
>
> Process[] originalProcesses = Process.GetProcessesByName("Excel");
>
> Application application = new ApplicationClass();
>
> Process[] newProcesses = Process.GetProcessesByName("Excel");
>
> ArrayList list = new ArrayList();
> foreach (Process newProcess in newProcesses) {
> bool isNew = true;
> foreach (Process originalProcess in originalProcesses) {
> if (originalProcess.Id == newProcess.Id) {
> isNew = false;
> break;
> }
> }
> if (isNew) list.Add(newProcess);
> }
>
> // Do your stuff
>
> foreach (Process process in list) {
> process.Kill();
> }
>
> This seems to work.
>[/color]
Looks to be rather safe.
Whit a very unlikly chance, that there could be started another instance of
Excel
just between the two GetProcessesByName calls. Very very unlikly and easy to
detect. The list will contain more than one process.
Not even sure if it was worth to mention that.


Tom P
Guest
 
Posts: n/a
#9: Nov 17 '05

re: Excel application.quit leaves instance of Excel running


Does the code in the finalize function finish???
If you call the GC.WaitForPendingFinalizers(); it waits syncronously
for the finalization queue to empty...... (all the objects which have
finalization methods)

If the code in the finalization section does not finish the process
will not terminate and just hang.
Has finalization on all you're objects completed? Check that you're
function terminates.

Closed Thread