Getting Started Common Acronyms FAQ Forum Help Forum Tips FTP Site Helpful GuidelinesInserting and Attaching images, videos, or files to postsProduct Community Directory SELECTsupport
Maik,
I think I have gotten that error when I forgot to initalize or did not use the right flags for that function. Other than that, the error usualy means that it can not get to the Projectwise server because of a network issue.
Hope that helps.
Hi,
I got my (and some other) VBA examples working, but not in Microstation. First of all I needed to get the ProjectWise/bin directory into the Sytem Path variable. Afterwards I was able to manage a log in from MS Office documents into ProjectWise. That worked fine, but with the same source code Microstation threw the error 55025 (invalid socket / connection to remote host broken).
I have done the logon from a non-integrated app many, many times, so I know it is possible. I am glad that Dave was able to help you with the c / vb interface.
Dave, thank you for your wrapper class, we'll check for it as soon as we compiled the dll.
Inspired by Rons statement I checked my vba from a Microstation DesignFile which is stored in ProjectWise, so I'm already logged in. As result I noticed that all of the functions worked (with the StrConv()-converted connection strings) and I was able to connect as another user or even in another datasource and read out the userID for example.
But our issue is to get access from an external "non-integrated application". So I hope it's possible with the API.
If you are using an integrated MicroStation session (i.e. the file opened in MicroStation is opened from ProjectWise) then you do not need to login.
You only need to login when you are using an external "non-integrated application"
HTH
Ron
I always have a hard time getting the strings to go to VB and come back right so I tend to write wrapper functions that do the string conversion for me. Getting the "Declares" right is also a challenge. It's a little extra work, but you end up with a reliable solution. So, for instance, my wrapper functions in the DLL look like this:
BOOL _mcmMain_GetDocumentIdByFilePath ( LPCSTR szFileNameP, long *lProjNoP, long *lDocNoP ) { LPGUID fileGuidsP = NULL; int iNumGuids = 0; BOOL bRetVal = FALSE;
if (SUCCESS == aaApi_GetGuidsFromFileName (&fileGuidsP, &iNumGuids, (char *) szFileNameP, TRUE)) { if (1L == aaApi_GUIDSelectDocument ((LPCGUID)&fileGuidsP[0])) { bRetVal = TRUE;
if (lProjNoP) { *lProjNoP = aaApi_GetDocumentNumericProperty (DOC_PROP_PROJECTID, 0); } if (lDocNoP) { *lDocNoP = aaApi_GetDocumentNumericProperty (DOC_PROP_ID, 0); } } }
aaApi_Free ((LPVOID) fileGuidsP);
return bRetVal; }
char gszPath[512];
extern "C" LPCSTR __stdcall ExpImpRasterChild_GetProjectPathFunctionToBeCalledFromVBA ( LPCSTR szDocumentFileNameP // i - full file name, regular chars from VB ) { AFX_MANAGE_STATE( AfxGetStaticModuleState() );
TCHAR wcFileName[512];
memset (wcFileName, 0, sizeof (wcFileName));
mbstowcs(wcFileName, szDocumentFileNameP, strlen (szDocumentFileNameP));
long lProjNo = 0L, lDocNo = 0L;
aaApi_Initialize (AAMODULE_ALL);
memset (gszPath, 0, sizeof (gszPath));
_mcmMain_GetDocumentIdByFilePath (szDocumentFileNameP, &lProjNo, &lDocNo);
if (lProjNo != 0 && lDocNo != 0) { TCHAR wcPath[512];
memset (wcPath, 0, sizeof (wcPath));
if (aaApi_GetProjectNamePath (lProjNo, TRUE, _T('\\'), wcPath, sizeof (wcPath) / sizeof (TCHAR))) { if (wcslen(wcPath) > 0) { wcstombs(gszPath, wcPath, wcslen (wcPath)); } } }
return gszPath; }
Notice use of LPCSTR vs. LPCTSTR as the the pointer type and the __stdcall decoration of the function signature. You'd export in a DEF file. The VBA (this is a MicroStation VBA macro) looks like this:
Public Declare Function ExpImpRasterChild_GetProjectPathFunctionToBeCalledFromVBA _ Lib "ExpImpRasterChild.dll" (ByVal sFileName As String) As Long
'function from operating system for converting strings from C format to VB format Public Declare Function lstrcpyn Lib "kernel32" Alias "lstrcpynA" _ ( _ ByVal lpString1 As String, _ ByVal lpString2 As Long, _ ByVal iMaxLength As Long _ ) As Long
'strings coming back from a DLL (C Strings) need this to be turned into VB Strings Public Function GetStringFromBuffer(ByVal lRetVal As Long) As String Dim sStringVal As String Dim lNewSize As Long sStringVal = VBA.Space(512) lNewSize = Len(sStringVal) Call lstrcpyn(sStringVal, lRetVal, lNewSize - 1) Dim iFind As Integer iFind = InStr(sStringVal, " ") If iFind <> 0 Then GetStringFromBuffer = VBA.Left(sStringVal, iFind - 2) Else GetStringFromBuffer = sStringVal End If End Function
Public Sub CmdShowPWPath()
Dim lResp As Long lResp = ExpImpRasterChild_GetProjectPathFunctionToBeCalledFromVBA(ActiveModelReference.DesignFile.FullName) Dim sPathName As String sPathName = GetStringFromBuffer(lResp)
MsgBox "PWPath: " & sPathName
End Sub
I spent too much time trying to get those Declares right and decided this was the most efficient approach. Maybe not the best solution for VB only developers, but then again, I'd never recommend doing a lot of PW customization in VB.
Dave
Please see example by private email.
Best Regards,
Ian Emery.
Hej,
I forgot to transform my strings to LCPWSTR type (whatever) and tryed following example.
Public Declare Function aaApi_Initialize Lib "DMSCLI.dll" (ByVal ulModule As Long) As Long
Public Declare Function aaApi_Login Lib "DMSCLI.dll" (ByVal lDsType As Long, ByVal lpctstrDSource As String, ByVal lpctstrUser As String, ByVal lpctstrPassword As String, ByVal lpctstrSchema As String) As Boolean
Public Declare Function aaApi_LoginDlg Lib "DMAWIN.dll" (ByVal lDsType As Long, ByVal lptstrDataSource As String, ByVal lDSLength As Long, ByVal lpctstrUsername As String, ByVal lpctstrPassword As String, ByVal lpctstrSchema As String) As Boolean
Public DataSourceName As String Public UserName As String Public Password As String
Sub Login()
init = aaApi_Initialize(AAMODULE_ALL) DataSourceName = "ppwsrv:pwmtst" UserName = "testuser" Password = "pwd"
If aaApi_Login(AAAPIDB_UNKNOWN, StrConv(DataSourceName, vbUnicode), StrConv(UserName, vbUnicode), StrConv(Password, vbUnicode), StrConv(vnNullString, vbUnicode)) = False Then LoginDlg = aaApi_LoginDlg(AAAPIDB_UNKNOWN, StrConv(DataSourceName, vbUnicode), Len(StrConv(DataSourceName, vbUnicode)), StrConv(UserName, vbUnicode), StrConv(Password, vbUnicode), StrConv("", vbUnicode))
End If
init returns true, the first LogIn false and the LogInDlg opens the LogIn dialog where my datasourcename and username are filled in but I need to fill in password by myself. Unfortunately the LogIn with dialog failed too. It throws error 55025 - invalid socket and sometimes error 32768 - logIn error (but can't reproduce it now). My string conversion works as the passed datasourcename and username was readable in dialog. I searched for a way to implement the c type strings but found just StrConv() to get the usual vb strings to (I hope) a compareable structure in vbUnicode. There was a BDNzine example in wiki using this technique, but a helper class was missing to use the whole example. Without the conversion those values looked like gibberish (灰獷癲琺獥獴档汵敺敥). But I didn't find an alternative string type for the declaration of the aaApi functions.
Maybe one of you knows a better way to implement lcpwstr or help me otherwise.
Thank you, Maik.
Marek,
I would also suggest that you get the handle to the logged on datasource with m_hDataSource = aaApi_GetActiveDatasource() so you can log out with aaApi_LogoutByHandle(m_hDataSource);
By the way, If you do logon with more than one logon, the last logon wins while it is logged in, then once you log out you are still logged in as the previous logon. Make sure your login(s) match your logout(s).
Dear Maik,
First use AAAPIDB_UNKNOWN in the login functions
I would replace the aaApi_LoginAdmin with aaApi_Login to allow alow single sign on - you can login as an administrator with aaApi_Login there is a differnce between the two but for a normal user side application aaApi_Login should suffice (for normal or admin user) aaApi_LoginAdmin has additional requirements.
if this call fails the use aaApi_LoginDlg to show the login dialog note the return type is IDOK etc.
if ! aaApi_Login then
if(! aaApi_LoginDlg then
really fail..
else
success..
Also make sure your vb strings are in the correct format they may need to be convered from VB strings to c type LPCWSTR and have the correct null terminator. I tryed this some time ago i was not really successful and spent more time converting vb data type to C/C++ data types than any thing else.
Ian Emery
Hi
and thanks for your answers. I got the ProjectWise SDK installed and I tried to get access by Microstation VBA. Therefore I wrote the following source code:
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_AdminLogin Lib "DMSCLI.dll" (ByVal lDsType As Long, lpctstrDSource As String, ByVal lpctstrUser As String, ByVal lpctstrPassword As String) As Boolean 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() 'Initialize the API result1=aaApi_Initialize(AAMODULE_ALL)
'Login to PW as Admin using Userdata result2=aaApi_AdminLogin(AAAPIDB_ORACLE, "ppwsrv:pwmtst", "username", "password")
'Login to PW using single sign-on result3=aaApi_Login(AAAPIDB_ORACLE, "ppwsrv:pwmtst", vbNullString, vbNullString, vbNullString)
result4=aaApi_GetCurrentUserId() End Sub
As results I got true for the Initialize function but false for the two LogIn functions and zero for the UserID (because access wasn't established).
If I'm logged on to ProjectWise Explorer and run this example out of a Microstation DGN stored in PW without the LogIn functions the aaApi_GetCurrentUsreId function will return the correct ID of the active user. But I need access from desktop without having PW Explorer started.
The references of the mvba are nothing but the default references. Is there anything wrong with my datasource string? I tried nearly everything ^^ I also tried using AAAPIDB_UNKNOWN instead of AAAPIDB_ORACLE. I hope someone may help my and give me some hints to get started with this. I guess the rest would be easier.
Thanks in advance,
Maik.
Yes you will definately need the SDK. Based on your example of what you are trying to achieve you can do this all directly within the VBA application without the need for COM. You will need the SDK docs (help files) to locate the functions you require, then you can declare them in your VBA/VB/VB.NET code.
We have done quite a few VBA routine amendments for existing customers to integrate legacy applications into ProjectWise.
Yes you need the SDK in order to access the libraries that tie into Projectwise Explorer. I would recomend writing a COM object in C++ for your ProjectWise funtionality (init, logon, check out file, check in file, etc.) You can then call the COM object with MSVBA. If you want to use VB.Net, you will still need to write a wrapper class for the function calls you want to use. Somebody posted an example of using VB with the api, but VB is limited what it can do without some interface help. At least this has been my experience.
We are introducing ProjectWise (XM) in our company to manage our operational data. In this process I need to customize some of our self written applications. Those are written in vba (mvba) or VB.net and are used to read and scan files (ascii format) and drop them - dependent on the file content - in a directory on a server. Now we want our tools to store the files in ProjectWise.
For now I searched for some simple examples how to access ProjectWise with Microstation VBA (e.g. ‘Using The ProjectWise API In VBA') or VB.net but none of the posted ones did work well (as I didn't have the SDK?). Does anyone have a good sample to start with and to get used to this topic (as I am new to this)? I just need to login to the server, create a document and maybe attach some environmental attributes. Do I need to have the SDK installed for my purpose?
I'd be grateful for any help and example.
Best regards,