Groups | Blog | Home
all groups > inetserver asp components > november 2003 >

inetserver asp components : Excel Thread Left in System


CST
11/14/2003 11:20:53 AM
Hi All,

I have run into a strange occurrence. Basically I want
to open up an Excel file and do a save as to html (I know
office automation on server is bad). I wrote a small com
application to do this. Please see the code below:

Option Explicit

Public Function XLSTest(XLSFileName As String)
Dim oXLSApp As Excel.Application
Dim oXLSWB As Excel.Workbook
Dim strXLSFile As String, strFullPath As String

Set oXLSApp = CreateObject("Excel.Application")
oXLSApp.Visible = True
oXLSApp.AskToUpdateLinks = False
oXLSApp.DisplayAlerts = False

strFullPath = "C:\Temp\"
strXLSFile = "C:\Temp\" & XLSFileName & ".xls"

Set oXLSWB = oXLSApp.Workbooks.Open
(FileName:=strXLSFile)
ActiveWorkbook.SaveAs FileName:=strFullPath &
XLSFileName, _
FileFormat:=xlHtml, ReadOnlyRecommended:=False,
CreateBackup:=False

oXLSWB.Close False
Set oXLSWB = Nothing
oXLSApp.Quit
Set oXLSApp = Nothing
End Function

This com object is called from an asp page:
<%
' *** Objects ***
Dim oRpt

Dim strFile, strPath
strFile = "Test"

Set oRpt = Server.CreateObject("XLSRun.XLSTest")
oRpt.XLSTest(strFile)

set oRpt = Nothing
%>

Everything works as expected (the html file(s) are
created), but the strange thing is the instance of Excel
is never destroyed. If you open up task manager and run
the asp page you will see the instance of Excel.exe
running. When the program finishes, I thought that it
would kill that instance of Excel, but it doesn't. Why
won't that instance of Excel go away. I believe that I
am destroying all of the references to Excel in my VB
code. Am I doing something obviously wrong? Please
help..

I am using VB6 (ActiveX dll) and running IIS 5.0.

TIA
Con Tang
11/14/2003 8:40:53 PM
I understand what you are saying and thank you for the response. I am
pretty sure that my code is correct and I destroy everything properly.
I just don't understand why it still leaves it out there. Have you
tried it or are able to recreate the issue? Outside of keeping track of
the PID, and killing it that way, is there any other way to ensure that
it gets destroyed? I am open to suggestions (please be kind, i know
office automation on server is not supported by Micro$ft). Thanks again
for the reply.

*** Sent via Developersdex http://www.developersdex.com ***
Chris Barber
11/15/2003 2:17:37 AM
Excel is what's known as an ActiveXEXE Server and is designed to instantiate
multiple instances of 'itself' for multi-workbook usage. However, this means
that - by design - it will persist even after all references to it have been
destroyed.
Usually this is because the code failed or because the code 'forgot' to
close the application instance before releasing the reference.
This is one of the many reasons that Excel, Word etc. are frowned upon for
web server instantiated usage - it can leave multiple copies divorced in the
system without means to kill them (apart from a reboot that is).

Chris.

[quoted text, click to view]
Hi All,

I have run into a strange occurrence. Basically I want
to open up an Excel file and do a save as to html (I know
office automation on server is bad). I wrote a small com
application to do this. Please see the code below:

Option Explicit

Public Function XLSTest(XLSFileName As String)
Dim oXLSApp As Excel.Application
Dim oXLSWB As Excel.Workbook
Dim strXLSFile As String, strFullPath As String

Set oXLSApp = CreateObject("Excel.Application")
oXLSApp.Visible = True
oXLSApp.AskToUpdateLinks = False
oXLSApp.DisplayAlerts = False

strFullPath = "C:\Temp\"
strXLSFile = "C:\Temp\" & XLSFileName & ".xls"

Set oXLSWB = oXLSApp.Workbooks.Open
(FileName:=strXLSFile)
ActiveWorkbook.SaveAs FileName:=strFullPath &
XLSFileName, _
FileFormat:=xlHtml, ReadOnlyRecommended:=False,
CreateBackup:=False

oXLSWB.Close False
Set oXLSWB = Nothing
oXLSApp.Quit
Set oXLSApp = Nothing
End Function

This com object is called from an asp page:
<%
' *** Objects ***
Dim oRpt

Dim strFile, strPath
strFile = "Test"

Set oRpt = Server.CreateObject("XLSRun.XLSTest")
oRpt.XLSTest(strFile)

set oRpt = Nothing
%>

Everything works as expected (the html file(s) are
created), but the strange thing is the instance of Excel
is never destroyed. If you open up task manager and run
the asp page you will see the instance of Excel.exe
running. When the program finishes, I thought that it
would kill that instance of Excel, but it doesn't. Why
won't that instance of Excel go away. I believe that I
am destroying all of the references to Excel in my VB
code. Am I doing something obviously wrong? Please
help..

I am using VB6 (ActiveX dll) and running IIS 5.0.

TIA

Chris Barber
11/15/2003 10:05:57 AM
Being realistic it is possible to kill a process that is divorced and in
fact I have done so on many occasions whilst writing tracker apps that
monitor a process and restart it if it hangs.
However, they are not that easy to get right and require some API calls into
Windows - this would require you to write / get hold of a DLL component to
do the work.
There are other possibilities with using third party Excel components such
as Excel Speedwriter.
Other than that, all you can do is try to find the source of the issue by
debugging and running Excel visible.

Destroying everything (references in your code) correctly is not really the
issue here - all your references go out of scope when the ASP page completes
anyway and as such they get destroyed then. What does matter is that your
automation calls are successful in their attempt to tell Excel to close and
quit. I haven't used Excel like this for a long time (4 years now) and I'm
sure that someone else might be able to confirm that your automation code is
correct.

Hope this helps.

Chris.

[quoted text, click to view]
I understand what you are saying and thank you for the response. I am
pretty sure that my code is correct and I destroy everything properly.
I just don't understand why it still leaves it out there. Have you
tried it or are able to recreate the issue? Outside of keeping track of
the PID, and killing it that way, is there any other way to ensure that
it gets destroyed? I am open to suggestions (please be kind, i know
office automation on server is not supported by Micro$ft). Thanks again
for the reply.

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!

Tom Kaminski [MVP]
11/17/2003 9:07:32 AM
[quoted text, click to view]

This explains in detail why it is bad to use office on the server side ...
http://support.microsoft.com/?kbid=257757

--
Tom Kaminski IIS MVP
http://www.iistoolshed.com/ - tools, scripts, and utilities for running IIS
http://mvp.support.microsoft.com/
http://www.microsoft.com/windowsserver2003/community/centers/iis/


Pat [MSFT]
11/17/2003 9:27:06 AM
The reason it stays is that IIS does not call CoFreeUnusedLibraries() which
is what Excel would need to shutdown. Starting w/Win2k3,
CoFreeUnusedLibraries is called every 5 minutes or so to do some additional
cleanup. The reason you don't want it called all the time is that the
process (or any COM object container/dll) could be re-used rather than
having to be re-loaded/initialized from scratch which is very, very
expensive (especially w/Office Automation). In web scenarios, it is not
unusual for a refcount to bounce off 0, even under a load during, and if it
unloaded immediately, you would get a lot of unneccessary (and performance
killing) thrashing.

BTW, this is the same reason why when you instantiate a COM object (dll) you
cannot replace it w/out killing the hosting process.


Pat

[quoted text, click to view]

John Beschler
11/17/2003 12:01:03 PM
Chris,

You bring up an interesting question. Would it be possible
to store the ProcessID for the istance of EXCEL someplace -
in a SQL table for example - and then retrieve it in
another process and use it to kill the instance?

Just curious.


[quoted text, click to view]
AddThis Social Bookmark Button