?
Solved

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

Posted on 2013-06-11
7
Medium Priority
?
565 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

 

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

Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

It’s the first day of March, the weather is starting to warm up and the excitement of the upcoming St. Patrick’s Day holiday can be felt throughout the world.
Access custom database properties are useful for storing miscellaneous bits of information in a format that persists through database closing and reopening.  This article shows how to create and use them.
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses
Course of the Month9 days, 4 hours left to enroll

764 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