Create Documents using SDK

Hi guys,

I want to, whenever a user click in a option created in PW and select a File from a FileDialog, this file should be created in PW. The first step of it (Create menu option and FileDialog) was acomplished succesfully. Now, i'm having problems to create the selected file as a document in PW. I tried what is described in this link http://communities.bentley.com/products/projectwise/projectwise_programming/f/342995/t/56503.aspx, but with no success. Could someone help me? Here is the code that i'm trying to create the document in PW (It's in C++ using MFC):

LONG docID = lpDocItem->lDocumentId;
LONG projectID = lpDocItem->lProjectId;

LONG *lngDocID;
*lngDocID = 0;

LONG lngAppID = aaApi_GetFExtensionApplication(L"pdf");
LONG lngWorkSpaceID = aaApi_GetWorkspaceProfileId(projectID, 0);

LPWSTR strWorkingDir = L" ";
BOOL status = aaApi_CreateDocument(lngDocID, projectID, 0, AADMS_FTYPE_UNKNOWN ,
AADMS_ITYPE, lngAppID, 1, lngWorkSpaceID, FileDlg.GetPathName(),
FileDlg.GetFileName(), FileDlg.GetFileName(), NULL, NULL,
false, AADMSDOCCREF_DEFAULT, strWorkingDir,
512, 0);
  • If it helps, "strings" were a particularly challenging aspect of C++/CLI for me because in C++ native, you can move between a pointer and an array pretty easily, but with managed code, I remember having to either build an object like you have done, with the "right" data/structure and pass (copy) the information that way, or by "pinning" a memory location in the managed area so that a pointer to it was valid, at least for as long as I needed it for. Of course, your particular problem may be something entirely different!

    Perhaps someone else "listening in" can point you in the right direction as far as how to pass in a string without the side effects that you are experiencing?
  • Thanks for the sample code Dan and thanks for taking the time to look into this for me.

    I built your sample code and can confirm that it's working as designed. I guess the problem is with the CLI somehow changing the string although I can't see where as a visual inspection of the string inside the PW hook function looks valid...

    Regarding my previous post, I was simply providing my reasoning for choosing to use CLI. I appreciate your input and can understand your need to simplify the problem down to a known implementation.

    Thanks.
  • Fred,

    FWIW, I wasn't advocating that you (or anyone else) use a specific language/tool, just that I'm not particularly knowledgeable in C++/CLI.  I found that I spent too much time trying to determine how things were being managed (or not managed), rather than solving the "problem" once (i.e. via PInvoke).  If C++/CLI works for you, then its OK to use.  Just keep in mind that you (the programmer) have to follow the "rules" of your language/tool of choice!  :-)

    The call to aaApi_ChangeDocumentFile() works for both a local path and a UNC path in C++ unmanaged code, so I suspect it's something about how C++/CLI (or your specific useage) is the root of the behavior that you are experiencing and not a "bug" in the ProjectWise APIs..

    Here's my test code as a VC++ (VS 2010) console application with hardcoded values using ProjectWise v08.11.11.559:

    #include "stdafx.h"
    
    #include "AAAPI.H"
    #include "AADMSAPI.H"
    #include "renametest.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    CWinApp theApp;
    
    using namespace std;
    
    LONG PWlastError()
    {
    	LONG status = aaApi_GetLastErrorId();
    
    	LPCWSTR errorMessage = aaApi_GetLastErrorMessage();
    	LPCWSTR errorDetail = aaApi_GetLastErrorDetail();
    
    	wcout << L"Status: " << status << endl;
    	if(NULL != errorMessage)
    		wcout << L"Error:  " << errorMessage << endl;
    
    	if(NULL != errorDetail)
    		wcout << L"Detail: " << errorDetail<< endl;
    	return status;
    }
    
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
    	int nRetCode = 0;
    
    	WCHAR szDSN[256] = {L"win2k8vm:training01"};
    	WCHAR szUsername[256] = {L"admin"};
    	WCHAR szPassword[256] = {L"admin"};
    
    	wcout << L"Initializing API..." << endl;
    	aaApi_Initialize(AAMODULE_ALL);
    
    	if(!aaApi_Login(AAAPIDB_UNKNOWN, szDSN, szUsername, szPassword, NULL))
    	{
    		PWlastError();
    		nRetCode = -1;
    	}
    	else
    	{
    		wcout << L"Login successful..." << endl;
    
    		WCHAR FileName1[] =  L"C:\\TEMP\\testFile1.txt";
    		WCHAR FileName2[] = L"\\\\NAOU11373\\TEMP\\testFile2.txt";
    
    		wcout << FileName1 << endl;
    		wcout << FileName2 << endl;
    
    		if(!aaApi_ChangeDocumentFile(285, 4, FileName1))
    		{
    			PWlastError();
    			nRetCode = -1;
    		}
    
    		if(!aaApi_ChangeDocumentFile(285, 5, FileName2))
    		{
    			PWlastError();
    			nRetCode = -1;
    		}
    
    		// logout
    		aaApi_LogoutByHandle(aaApi_GetActiveDatasource());
    		nRetCode = 0;
    	}
    	aaApi_Uninitialize();	
    
    	return nRetCode;
    }
    

    HTHs

  • Hi Dan,
    thanks for your response. Yes, I'm using CLI as I'm exposing the methods via a SOAP service to make them available to other applications outside of the ProjectWise infrastructure. I did initially try to get PInvoke working but was having problems figuring out the syntax for the various methods I needed to use so I gave up and went with CLI. It's working for me and I have quite a bit of infrastructure built on top of it now so would be reluctant to change!
    It's possible that it's something to do with using CLI but I've tried inspecting the path during a debug session and don't see any differences in how the strings are represented. I even added an "action" hook function to inspect the strings during the aaApi_Add/ChangeDocumentFile call but could not see any discernible difference between a UNC path and a local path.
  • Looks to me like you are using C++/CLI. I've only used that once and found it to be much more difficult for me conceptually compared to native C++ or calling unmanaged code from C# via PInvoke. Perhaps someone with more C++/CLI experience can take a closer look at your code.

    I suspect that the behavior you are experiencing is probably due to C++/CLI specifics. Can you reproduce the behavior with native C++?

    If I get a chance later today, I'll try both a local path and a UNC path via C++ and see if I experience the same behavior.