Solved

Spawned Process in Win 2008 / IIS 7.5 Doesn't Close

Posted on 2013-06-11
7
548 Views
Last Modified: 2013-06-17
Old old website, classic VB ASP, invoking a macro in an MS Access 2000 database.

      Set obj = GetObject("e:\data\Admin.mdb")
      obj.DoCmd.RunMacro "UpdateEmailTable"
      Set obj = Nothing

This has run for years without issue until we switched from IIS 6 on Win 2003 over to IIS 7.5 on Win 2008.  It still runs okay, but it keeps a lock on the database when it's done and the spawned process does not close.

The macro is a simple one, it deletes a table and imports a spreadsheet in its place.

Symptoms:

1. Upon invoking GetObject, the system spawns an MSACCESS.EXE process under the IIS user.
2. It does the macro work.
3. The process stays open, leaving a hold on the lockfile (Admin.ldb)

If I kill the process manually, I can delete the lock file.  If I don't kill the process and the script runs a 2nd time, there will be a second MSACCESS process sitting open.  Rinse & repeat until there's a dozen processes and someone notices.  I need to fix it.

I've tried adding some lines to the code prior to setting obj = Nothing, both:

      obj.DoCmd.Close

and

      obj.Close

But neither seems to have the desired effect of closing the process when it is done.

On Win 2003/IIS6 it closes.  So I don't know if it's a Win 2008 thing, an IIS 7.5 thing, or some permissions issue with the IIS user being allowed to spawn a process but not close it?  I did try making the IIS user a member of Administrators just as a test but it had no effect.
0
Comment
Question by:wegee2
  • 6
7 Comments
 
LVL 20

Expert Comment

by:clarkscott
ID: 39237691
Maybe it's in the GETOBJECT.
I'd try
DIM DB AS DATABASE
SET DB = OPENDATABASE (YOURPATH)

'---  run your query

db.close
set db = nothing


Scott C
0
 

Author Comment

by:wegee2
ID: 39238391
Scott, I've tried various other methods of running this macro without using GetObject:

Set objAccess = Server.CreateObject("Access.Application")
objAccess.OpenCurrentDatabase Server.MapPath("e:\data\Admin.mdb")
objAccess.DoCmd.RunMacro "UpdateEmailTable"
objAccess.DoCmd.Quit 2  'quit without saving, no prompt
Set objAccess = Nothing

GetObject on the .mdb returns an object of type Application, so I think it's merely a shortcut to the above code.

I've also tried adding the Quit command to the end of the macro itself.

Both of these methods will release its hold on the lock file (good), but the process itself stays open still.

I've read suggestions about the database being corrupt - it is not.  That Compact On Close is enabled - it is not.  That there are subforms using boolean logic in them - there are none.

The process name is MSACCESS.EXE*32.  I'm wondering if it's a problem with svchost closing a 32-bit process.  I discount this because if I open the database manually (outside of IIS), it opens Access 2000 under my username, which is the same process name, MSACCESS.EXE*32.  The difference being when I close it, the process goes away.

/hair pull
0
 

Author Comment

by:wegee2
ID: 39238674
Found this as it relates to a similar symptom in a .NET environment:

http://support.microsoft.com/?kbid=317109

But I can't seem to figure out if classic ASP has anything similar.  From all I read setting it = nothing in classic will destroy all references to the COM object.  Obviously that is not the case here.

Still looking.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:wegee2
ID: 39238838
Loaded Process Explorer and it appears the process is just sitting idle, which makes sense because its work was completed an hour ago.

For S&G (mostly because I don't know enough to not be dangerous) I created a memory dump of the still-running MSACCESS.EXE*32 process and opened it in WinDbg.

The call stack:

00 : ntdll!ZwWaitForWorkViaWorkerFactory+0xa
01 : wow64!Wow64EmulateAtlThunk+0x1c993
02 : wow64!Wow64SystemServiceEx+0xd7
03 : wow64cpu!TurboDispatchJumpAddressEnd+0x2d
04 : wow64!Wow64SystemServiceEx+0x1ce
05 : wow64!Wow64LdrpInitialize+0x429
06 : ntdll!RtlIsDosDeviceName_U+0x24c87
07 : ntdll!LdrInitializeThunk+0xe
0
 

Accepted Solution

by:
wegee2 earned 0 total points
ID: 39238951
I developed a solution that works after digging some more through MS.. I just don't know if I like it yet.

Sub TerminateAccess()
	Set objServices = GetObject("winmgmts:\\.\root\CIMV2")
	set objProcessSet = objServices.ExecQuery("SELECT Handle, Name FROM Win32_Process")
	For Each Process in objProcessSet
		Dim ownername
		Dim ret
		ret = Process.GetOwner(ownername)
		If ret <> 0 Then 
			'can't verify owner
			ownername = "unknown"
		End If

		If ownername = "IIS_USER" and Process.Name = "MSACCESS.EXE" Then Process.Terminate()
	Next
End Sub

Open in new window

0
 

Author Comment

by:wegee2
ID: 39241549
I thought I had it nailed.  The Access.Application object has a property .hWndAccessApp which returns the window handle of the running process.  However, there’s nothing that tells you what the process ID is.  There is a function in user32 called GetWindowThreadProcessId that will take a window handle and return the thread ID and, optionally, the process ID.  However, you can’t call it from vbscript directly.  VB6 you can declare it, vbscript you cannot.  The workaround is to create a COM object to call it for you, but that’s a lot of work for what I think is very minimal return.  It would be the IDEAL solution because I could then get the exact process ID and terminate it specifically rather than looping through looking for the process to terminate it.

Anyway, I'm satisfied enough with this solution to not bother the EE community any longer with it.  Hopefully when we migrate this to .NET & MSSQL, this becomes a non-issue anyway.
0
 

Author Closing Comment

by:wegee2
ID: 39252575
This ultimately kills the dangling process.  No actual methods on the object itself will do it.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

I see at least one EE question a week that pertains to using temporary tables in MS Access.  But surprisingly, I was unable to find a single article devoted solely to this topic. I don’t intend to describe all of the uses of temporary tables in t…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
Using Microsoft Access, learn some simple rules for how to construct tables in a relational database. Split up all multi-value fields into single values: Split up fields that belong to other things into separate tables: Make sure that all record…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now