I am struggling with some MSAccess automation issues. Basically, we
have a .Net application that uses MSAccess for reporting (legacy
code). We are able to launch MSAccess fine and even work with the
MSAccess COM objects to run our reports (using GetObject(<MDB Path>) -
see http://support.microsoft.com/default...&Product=vbNET
for info on how to do this).
The problem that we are running into is that if our Access database is
already opened, we want to use it instead of opening up another
instance.
I've included the code I've got so far in case it helps with the
problem. The problem line of code is in ValidateAccessHandle (the
exact line is - mAccessHandle =
GetObject(imsAppConfig.DefaultMainMenuMDB)). If this line is commented
out and an instance of MSAccess is already running with our database,
a new MSAccess window will be launched, but the original MSAccess
window will be returned from GetObject(<MDB Path>). If we leave it in,
on some machines, if MSAccess isn't running, it will create an
instance without the window. Since we need pass MSAccess command-line
parameters, this doesn't work for us (also, a report tends to be more
interesting when you can see it :).
Any help is appreciated, thanks!
Private Function ValidateAccessHandle() As Boolean
If mAccessHandle Is Nothing Then
Try
' Check to see if there is an orphaned window.
' If we don't check, we'll end up opening another
window, but using the existing one anyway.
mAccessHandle =
GetObject(imsAppConfig.DefaultMainMenuMDB)
If mAccessHandle Is Nothing Then Return False
Catch ex As Exception
' On some machines, GetObject throws an untyped
exception when the file is not found.
mAccessHandle = Nothing
Return False
End Try
End If
Try
mAccessHandle.run("")
Return True
Catch ex As System.Runtime.InteropServices.COMException When
ex.ErrorCode = -2146820336
Debug.Assert(ex.Message = "You made an illegal function
call.", "Unexpected error message.", String.Format("The message for
this exception was expected to be 'You made an illegal function call.'
but was actually '{0}'", ex.Message))
' The Access window was closed normally (reproducable by
closing Access) and we need to reopen it.
mAccessHandle = Nothing
Return False
Catch ex As System.Runtime.InteropServices.COMException When
ex.ErrorCode = -2147023174
Debug.Assert(ex.Message = "The RPC server is unavailable.
(Exception from HRESULT: 0x800706BA)", "Unexpected error message.",
String.Format("The message for this exception was expected to be 'The
RPC server is unavailable. (Exception from HRESULT: 0x800706BA)' but
was actually '{0}'", ex.Message))
' The Access window was forced closed (reproducable by
opening Task Manager and killing all instances of MSACCESS.exe after
launching it).
mAccessHandle = Nothing
Return False
Catch ex As System.Runtime.InteropServices.COMException When
ex.ErrorCode = -2146825771
' This is expected. "" is not a valid method.
Return True
End Try
End Function
Private Function LaunchAccessClient() As Boolean
' The Access client is already launched.
If ValidateAccessHandle() Then Return True
Dim cmdLine As String = BuildCommandLine()
Shell(cmdLine, AppWinStyle.MinimizedNoFocus, True,
imsAppConfig.WaitTimeForAccess)
mAccessHandle = GetObject(imsAppConfig.DefaultMainMenuMDB)
Return ValidateAccessHandle()
End Function
Public Function BuildCommandLine() As String
'If the current user is "IMSAdmin" then start the access
client using the SystemAdmin user.
'Otherwise start the access client as the MRPUser.
Dim userName As String
Dim password As String
If imsAppConfig.LoginAsAdmin Then
userName = "IMSAdmin"
password = ""
ElseIf imsAppConfig.LoginAsSystemAdmin Then
'If the Login in as SystemAdmin is checked then log the
user in as SystemAdmin.
userName = "SystemAdmin"
password = "" ' removed for obvious reasons :)
Else
userName = "MRPUser"
password = "" ' removed for obvious reasons :)
End If
Dim runtimeSwitch As String
If imsAppConfig.StartWithRuntime Then
runtimeSwitch = " /Runtime "
Else
runtimeSwitch = ""
End If
'Check whether or not to call Startup
Dim startupSwitch As String
If imsAppConfig.RunAccessStartup Then
startupSwitch = " /x mcrAutoExec "
Else
startupSwitch = ""
End If
Dim cmdLine As String
Dim profile = GetProfile()
cmdLine = String.Format("""{0}"" ""{1}"" {2}{3} /profile
""{4}"" /user {5} /pwd {6} /cmd <User>{7}</User><UseCustom>{8}</
UseCustom><CustomGraphics>{9}</CustomGraphics>", AccessLocation,
imsAppConfig.DefaultMainMenuMDB, runtimeSwitch, startupSwitch,
profile, userName, password, imsContext.Current.UserName,
imsContext.Current.UseCustomObjects,
imsAppConfig.CustomGraphics.ToString())
Return cmdLine
End Function