WIN32OLE -- cannot terminate Excel process

D

djlewis

I've read all the forum stuff on getting the Excel process to
terminate. Yet the following code does not do that -- Excel.exe
remains in task manager...

excel = WIN32OLE::new('excel.Application')
ewb = excel.workbooks.add( t_path + "TTI-DB-Template.xls")
ews = ewb.Worksheets.Item( 1)
ews.cells(1, 1).value = "sdfasd" # comment out to make it work

ewb.saveas( t_path + "Temptemp3.xls")

# not sure I need all this, but it can't hurt (or can it?)
ewb.Close(0)
excel.Quit()
WIN32OLE.ole_free( excel)
WIN32OLE.ole_free( ewb)
WIN32OLE.ole_free( ews)
excel = nil
ews = nil
ewb = nil
GC.start

However, if I remove the line: ews.cells(1, 1).value = "sdfasd", then
the Excel process DOES go away.

What'd going on here? How do I get rid of the Excel process if I put
anything into the worksheet/workbook?

Thanks. --David.
 
B

Bryan Richardson

You could kill the excel process... not sure how clean that is though.

Process.kill('KILL', excel.ProcessID)
 
D

djlewis

You could kill the excel process... not sure how clean that is though.

Process.kill('KILL', excel.ProcessID)

Yup, thought of that, and will do it if I can't figure out how to
terminate the process cleanly. So, how do I get the ProcessID?

Thanks. --David.
 
B

Bryan Richardson

require 'win32ole'

excel = WIN32OLE.new 'excel.Application'

puts excel.ProcessID
 
D

djlewis

require 'win32ole'

excel = WIN32OLE.new 'excel.Application'

puts excel.ProcessID

OK, thanks. Process.kill works nicely, if I know the processID. But
excel.ProcessID does not fly. In a casual browse through excel's
ole_methods, I don't see anything that would obviously do the trick.

I could always looks through the process, thus...

wmi = WIN32OLE.connect("winmgmts://")
processes = wmi.ExecQuery("select * from win32_process where
commandline like '%excel.exe\"% /automation %'")
for process in processes do
Process.kill( 'KILL', process.ProcessID.to_i)
end

That would kill ~all~ automation instances of Excel, which may be what
I want, but maybe not. So, I still don't see an easy way to find the
specific ProcessID, that is, without doing queries before and after
WIN32OLE.new 'excel.Application' and see what new excel process just
appeared.

--David.

Thanks. --David.
 
D

David Mullet

djlewis said:
I've read all the forum stuff on getting the Excel process to
terminate. Yet the following code does not do that -- Excel.exe
remains in task manager...

excel = WIN32OLE::new('excel.Application')
ewb = excel.workbooks.add( t_path + "TTI-DB-Template.xls")
ews = ewb.Worksheets.Item( 1)
ews.cells(1, 1).value = "sdfasd" # comment out to make it work

ewb.saveas( t_path + "Temptemp3.xls")

# not sure I need all this, but it can't hurt (or can it?)
ewb.Close(0)
excel.Quit()
WIN32OLE.ole_free( excel)
WIN32OLE.ole_free( ewb)
WIN32OLE.ole_free( ews)
excel = nil
ews = nil
ewb = nil
GC.start

However, if I remove the line: ews.cells(1, 1).value = "sdfasd", then
the Excel process DOES go away.

What'd going on here? How do I get rid of the Excel process if I put
anything into the worksheet/workbook?

Thanks. --David.

Your code runs fine on my machine, up through this point:

excel = WIN32OLE::new('excel.Application')
ewb = excel.workbooks.add( t_path + "TTI-DB-Template.xls")
ews = ewb.Worksheets.Item( 1)
ews.cells(1, 1).value = "sdfasd" # comment out to make it work
ewb.saveas( t_path + "Temptemp3.xls")
ewb.Close(0)
excel.Quit()

If I left out the remainder of your code, the Excel process terminated
properly.

If, however, I included the rest of your code verbatim...

WIN32OLE.ole_free( excel)
WIN32OLE.ole_free( ewb)
WIN32OLE.ole_free( ews)
excel = nil
ews = nil
ewb = nil
GC.start

...the Excel process did not terminate properly.

If I modified that code to this...

ews = nil
ewb = nil
excel = nil
WIN32OLE.ole_free( ews)
WIN32OLE.ole_free( ewb)
WIN32OLE.ole_free( excel)
GC.start

...the Excel process terminated properly.

My suggestions:

A) Set object variables to nil before calling ole_free.
B) Set object variables to nil in the reverse order that they were
created.
C) Don't bother with nil, ole_free, and GC.start if you don't need to.

Hope that helps.

David

http://rubyonwindows.blogspot.com
http://rubyonwindows.blogspot.com/search/label/excel
 
A

Adam Shelly

If I modified that code to this...

ews = nil
ewb = nil
excel = nil
WIN32OLE.ole_free( ews)
WIN32OLE.ole_free( ewb)
WIN32OLE.ole_free( excel)
GC.start

...the Excel process terminated properly.

My suggestions:

A) Set object variables to nil before calling ole_free.

I can see how you can free up object memory with
ews = nil;
#...
GC.start

But I'm not sure what calling ole_free after assigning to nil could
possibly do...
How is
ews = nil;
WIN32OLE.ole_free( ews)

any different from:
WIN32OLE.ole_free( nil)
?

-Adam
 
D

djlewis

I can see how you can free up object memory with
ews = nil;
#...
GC.start

But I'm not sure what calling ole_free after assigning to nil could
possibly do...
How is
ews = nil;
WIN32OLE.ole_free( ews)

any different from:
WIN32OLE.ole_free( nil)
?

-Adam

Thanks for all the suggestions. One of my problems was due to running
in a debugger (NetBeans) and stopping at a breakpoint to look at
processes, and sometimes even just killing execution right there.
That prevented the Excel process from terminating, perhaps because GC
did not finish its job.

Still, during debugging, that's a common occurrence, and can lead to a
lot of Excel processes hanging around. So I think the function simply
to kill all automation instances of Excel is handy to have while
debugging, used, say, at the beginning of the program. Here it is...

def kill_excel_automation_processes
wmi = WIN32OLE.connect("winmgmts://")
processes = wmi.ExecQuery("select * from win32_process where
commandline like '%excel.exe\"% /automation %'")
processes.each do |process|
Process.kill('KILL', process.ProcessID)
end
end

I don't know if there's a way to get something called upon manual
termination in the debugger. at_exit { } does not seem to do it in
NetBeans.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top