Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 571
  • Last Modified:

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.
0
wegee2
Asked:
wegee2
  • 6
1 Solution
 
clarkscottCommented:
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
 
wegee2Author Commented:
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
 
wegee2Author Commented:
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
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 
wegee2Author Commented:
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
 
wegee2Author Commented:
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
 
wegee2Author Commented:
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
 
wegee2Author Commented:
This ultimately kills the dangling process.  No actual methods on the object itself will do it.
0

Featured Post

Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now