After many long hours troubleshooting the “crash” of an automated instance of Microsoft Access 2007, I finally have a solution. An API call to terminate the instance I want to quit after I close the current database – CloseCurrentDatabase().
The project: automate the process of converting 200+ databases from Access 97 to Access 2007. I know… why so many databases? Long boring story, but legitimate and unavoidable situation. All databases are in use so manual conversion, aside from being painfully tedious, would not be ideal as managing which ones are converted, and when, and for who would be too difficult and timely.
The databases were created by many different people over many years, some had startup macros, others startup forms, which was my first hurdle. How to automate the opening of a database while bypassing the automatic events that fire when it is opened? Dev Ashish to the rescue: fGetRefNoAutoexec(). This function is my new best friend. Now I can audit all of these databases anytime, modifying this function.
So all is going well. I can open an instance of Access, bypassing automatic open events, time to code. Tables list old and new names, built in method ConvertAccessProject() works very well, update references in each database with new versions, re-link linked tables to links in new 2007 databases, each part working independently. Time to put it all together.
Argh!!!! &$*@%! What the hell is going on? Stepping through found that when Quit() method was called on the instance, Windows thought it was a crash. Ignoring it is no good, and leaving them open to close at the end — 200 dialogs? No. I needed to find a way to disable or hide this dialog.
All attempts to suppress or disable Windows Error Reporting (WER) failed. Manually, registry hacks, and group policy changes all went ignored and the dialog continues to show. I didn’t like that solution anyway but it was the first thing I could think of. Some googling revealed that there are many ways to disable WER but they don’t all work. So I am not alone. The above image is Microsoft’s WER form for Dr. Watson, DW20.exe.
I then tried different methods of creating my instance of Access. Early and late binding and explicit version specific CreateObject did not help. Every workaround produced the same problem, “crash”. When I removed the Quit() I found myself in task manager killing each process. That’s it! API to kill the process. Some fine tuning to this baby and this automation program will be saving me tons of time.
GetWindowThreadProcessId acc.hWndAccessApp, PID Ret = OpenProcess(PROCESS_TERMINATE, 0, PID) TerminateProcess Ret, 0
Sources:
API: Bypassing Autoexec
http://access.mvps.org/access/api/api0068.htm
How To Programmatically Close a Single Instance of a Windows-Based Program
http://support.microsoft.com/kb/176391/EN-US/