trouble with aaApi_Login(), and how do I find the correct DLL for declaring a function?

I'm learning how to use the ProjectWise API through VBA, and I'm trying to build a basic Hello World program.  So far, I have:

Public Declare Function aaApi_Initialize Lib "DMSCLI.dll" (ByVal ulModule As Long) As Long
Public Declare Function aaApi_GetCurrentUserId Lib "DMSCLI.dll" () As Long
Public Declare Function aaApi_Login Lib "DMSCLI.dll" (ByVal lDsType As Long, lpctstrDSource As String, ByVal lpctstrUser As String, ByVal lpctstrPassword As String, ByVal lpctstrSchema As String) As Boolean

Sub LogIn()

Dim result1 As Boolean
Dim result2 As Boolean
Dim result3 As Long

'Initialize the API
result1 = aaApi_Initialize(AAMODULE_ALL)
'Login to PW using single sign-on
result2 = aaApi_Login(AAAPIDB_UNKNOWN, "", vbNullString, vbNullString, vbNullString)
'Get ID for current user
result3 = aaApi_GetCurrentUserId()

End Sub

The aaApi_Login() call is returning false, and I don't know why. I want to use aaApi_GetLastErrorID() to inspect the problem, but I don't know which DLL to use for declaring it.

Short of running a dumpbin on every DLL in the ProjectWise\Bin folder and searching through each dump, is there an easier way to find out which DLL should be used to declare a given function? Is this information available somewhere in the SDK that I've overlooked?

  • Joshua,

    Here are a couple tips and the primary answer to your question.

    1. Although you may find a few posts on calling the ProjectWise APIs from Microsoft VBA, at this time it is not a fully supported path for several reasons.   The recommended path is to create yourself a ProjectWise API native code custom module in C/C++ allowing for providing your external (VBA) apps a simplified interface hiding the complexity of the underlying ProjectWise C/C++ code required to perform a given task.  Unfortunatley we do not have or provide a functional ProjectWise API to VBA type mapping guide and necessary function declarations required.
    2. Microsoft VBA allows a programmer to call functions declared in the Microsoft __stdcall convention when a public export in a .dll.  It is important that the application calling an exported function has the function's owning .dll in a readily available and searched application PATH.  If not, the external application will not be able to locate the .dll referenced and fail.  Always make sure that the application in question is "aware" of the required .dll or use a Microsoft tool like Microsoft Process Monitor (procmon) to find out where Windows is searching for .dlls for a given application.  For example, if you create a ProjectWise native code custom module it requires additional dependencies in the appropriate ..\ProjectWise\bin directory.  Your customization would also need to reside there, or provide early binding (application) pathing to find and load required dependent .dlls.  If you extend your custom module with exports and the __stdcall convention you can then use e.g. MicroStation VBA, Microsoft Excel VBA, etc. - IF you provide a correct working path to the ..\ProjectWise\bin directory and/or your own seperate .dll directory; if you chose not to place your customization in the ProjectWise bin directory.
    3. So, to answer your question you could use a Microsoft Visual Studio command shell and use the Visual Studio dumpbin.exe in conjuction with Microsoft Findstr.exe to provide effective filtering.  For example this keyin:

    dumpbin /EXPORTS *.dll | findstr "following aaApi_GetLastErrorId"

    Provides an abbreviated list (below) showing which .dll you would need to actively reference. 

    C:\Program Files (x86)\Bentley\ProjectWise\bin>dumpbin /EXPORTS *.dll | findstr "following aaApi_GetLastErrorId"
      Section contains the following exports for acledit.dll
      Section contains the following exports for Bentley.Crypto.1.0.dll

      Section contains the following exports for DMSGEN.dll
            198   C5 0000AF80 aaApi_GetLastErrorId = _aaApi_GetLastErrorId@0
      Section contains the following exports for dmslogapi.dll
      Section contains the following exports for dmsmapiclient.dll

    Please note the following:

    • All Function calls and searches should be performed in a case-sensitive manner to ensure that correct code is called and executed.  Microsoft VBA's environment does not always make the most strict programmer preferred options the default and therefore you should validate your VBA Project properties and ensure "Require Variable Declaration" use of "Break on All Errors" for development and debugging, and "Break on All Unhandled Errors" for users in production.  I always look at the top of Every source code Module, Class, and Form to make sure "Option Explicit" is set to best ensure valuable time is not wasted troubleshooting well hidden bugs. :)
    • I specifically did not tell Findstr.exe to be case insensitive with a "-i" argument since I want only lines that contain "following" in lowercase.
    • This approach also forces the programmer to know the exact case of the function in question, otherwise no results (or failing calls) will happen.
    • There may be better ways to do this from a command line or GUI tool like Depends.exe, etc.; however this was quick and provided the correct result.

    Feel free to reply to this thread to let us know if this or something else helped resolve the issue.



Reply Children