Bentley Communities
Bentley Communities
  • Site
  • User
  • Site
  • Search
  • User
  • Welcome
  • Products
  • Support
  • About
  • More
  • Cancel
ProjectWise Programming
  • Product Communities
  • Developers and Programming
  • ProjectWise Programming
  • More
  • Cancel
ProjectWise Programming
ProjectWise Programming - Wiki ProjectWise API access with C#
    • Sign in
    • -ProjectWise Programming - Wiki
      • -ProjectWise Code Snips and Samples
        • ProjectWise API access with C#
        • Using CORS feature with Web Services Gateway

     
     Questions about this article, topic, or product? Click here. 

    ProjectWise API access with C#

    The  ProjectWise SDK is a set of header files and link files that allow a C++ program to interface with the DLL files in the bin directory of ProjectWise.  You can interact with those DLL files with a C# program but in a different way.  The ProjectWise DLL files are standard C++ and do not have any COM or assembly interface to interact with.   In C# you have to use what is called Platform Invoke (p/Invoke).  This involves declaring each function you wish to call in a specific way to determine how the data is going to be passed from your program to the DLL and from the DLL to your program.   There are many web sites that talk about marshaling and p/Invoke.  There seem to be many approaches to accomplishing the same thing.  I am going to relate the methods that worked for me.

    You need System.Runtime.InteropServices in order to create the DLLImport definitions. This can be added with a using statement at the top of the file that has your API function definitions.  When I have an API function I want to use, I copy the definition from the help and then apply the tag and change the data types.

    Example from the API help:

    LONG aaApi_SelectProject(LONG lProjectID)

    Declaration for C# :

    [DllImport("c:\\Program Files\\Bentley\\ProjectWise\\bin\\dmscli.dll")]
    
    public static extern int aaApi_SelectProject(int lProjectId);

    With this declaration in  place you can use the function normally in your code.  It is best practice to create a library of functions in their own class and namespace to share among the programs you write for consistency.  However you may find that your declarations and how your code interacts with them vary some between 32-bit and 64-bit functions.

    Here is a list of mappings I use from API help to C# declaration.

    LONG                                      int
    ULONG                                   uint
    LPLONG                                 ref int
    BOOL                                      bool
    HAADMSBUFFER                   IntPtr
    LPCTSTR                                string (as argument), IntPtr (as return value)
    LPWSTR                                  StringBuilder

    Strings are handled differently than int and IntPtr for marshaling.  Here are the rules I follow.

    If string is in the argument then the tag looks like this: [DllImport("dmscli.dll",CharSet = CharSet.Unicode)]

    if LPCTSTR is in the return value in the help then you use IntPtr as the return value and use Marshal.PtrToStringUni() around the function to convert the return to a C# string.

    if you need to pass NULL to a string then use the keyword null.  If that causes an error, then change the type to IntPtr and pass IntPtr.Zero for the null value.

    When you use StringBuilder to pass a pointer to a string (LPWSTR), you have to define the MaxCapacity and use that value for your buffer length.

    Occasionally you will need to pass or get a structure.  You need to define the structure in your class with your declarations and it needs to be defined with the [StructLayout(LayoutKind.Sequential)] tag.

    Example:

    [StructLayout(LayoutKind.Sequential)]
    
    public struct AADOC_ITEM
    
    {
         public int lProjectId;
         public int lDocumentId;
    }

    You can not create hooks and menus in pure C# yet, you will need to create a C# COM object and a C++ stub that is called by ProjectWise.

     

     

    • ProjectWise API
    • PW API
    • c#
    • Share
    • History
    • More
    • Cancel
    • Dean Lyon Created by Dean Lyon
    • When: Wed, Dec 5 2012 9:37 AM
    • Robert Hook Last revision by Bentley Colleague Robert Hook
    • When: Wed, Jan 22 2020 2:14 PM
    • Revisions: 2
    • Comments: 1
    Recommended
    Related
    Communities
    • Home
    • Getting Started
    • Community Central
    • Products
    • Support
    • Secure File Upload
    • Feedback
    Support and Services
    • Home
    • Product Support
    • Downloads
    • Subscription Services Portal
    Training and Learning
    • Home
    • About Bentley Institute
    • My Learning History
    • Reference Books
    Social Media
    •    LinkedIn
    •    Facebook
    •    Twitter
    •    YouTube
    •    RSS Feed
    •    Email

    © 2021 Bentley Systems, Incorporated  |  Contact Us  |  Privacy |  Terms of Use  |  Cookies