Link to home
Start Free TrialLog in
Avatar of wegee2
wegee2

asked on

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

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.
Avatar of clarkscott
clarkscott
Flag of United States of America image

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
Avatar of wegee2
wegee2

ASKER

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
Avatar of wegee2

ASKER

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.
Avatar of wegee2

ASKER

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
ASKER CERTIFIED SOLUTION
Avatar of wegee2
wegee2

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of wegee2

ASKER

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.
Avatar of wegee2

ASKER

This ultimately kills the dangling process.  No actual methods on the object itself will do it.