"Incorrect Format" when calling PW SDK

We have several custom tools built with the ProjectWise SDK.  These run on Windows 10 workstations with ProjectWise Explorer 10.00.03.167.  We've recently refreshed several of these workstations, and while most of them now run these tools with no issues, running them on two of workstations throws an error for any call into the ProjectWise API.  On these machines, any call returns the Windows 0x8007000B error code with "An attempt was made to load a program with an incorrect format.".  The calling modules (which are C#.net) are all built as "Any CPU".  I've verified the PWBIN folder is in the Path Environment Variable, which I know when missing will throw a different error, but I checked it anyway.  Is there any other known issue with installing or configuring ProjectWise that might account for this?

Thanks.

Parents
  • Carl,

    More detail would help on what your tools are.  Typically this error (incorrect format) is because a 32-bit code is trying to call a 64-bit function or the other way around.

    If you look at my sample "SampleCallingC-ShareCodeFromMrrFile", you will see that I set the configuration to be x86 and Win32 because these will be called from ProjectWise Explorer, which is a 32-bit application.

    However, you can create your own tools to run as 64 or 32 bit since the SDK supports both.  So I would expect the "tools" that are returning the errors are ProjectWise Explorer "custom modules", but I could be wrong.

    Are all the machines that your tools are working OK on, 32-bit machines (Windows 10, 32-bit)?  And are the two machines that they fail on, 64-bit machines?

    If you can provide more details on the machines that "run the tools with no issues", and for the two machines where the tools return the error, that would be helpful.

    Also, details about your tools (custom module, code for MRR menus, stand alone applications, etc.) as well as how they are configured would be helpful.

    You might want to take a look at some of the sample code I posted here:  https://github.com/DanWilliamsAtBentleyDotCom 

    and take a look on how I have then configured for the debug build (I didn't bother making sure that any "release" build was configured properly).  For example, here's how I have a build configured for use by an MRR file:

    At least this is my best guess for now based upon what I can infer from your post!  : -)

Reply
  • Carl,

    More detail would help on what your tools are.  Typically this error (incorrect format) is because a 32-bit code is trying to call a 64-bit function or the other way around.

    If you look at my sample "SampleCallingC-ShareCodeFromMrrFile", you will see that I set the configuration to be x86 and Win32 because these will be called from ProjectWise Explorer, which is a 32-bit application.

    However, you can create your own tools to run as 64 or 32 bit since the SDK supports both.  So I would expect the "tools" that are returning the errors are ProjectWise Explorer "custom modules", but I could be wrong.

    Are all the machines that your tools are working OK on, 32-bit machines (Windows 10, 32-bit)?  And are the two machines that they fail on, 64-bit machines?

    If you can provide more details on the machines that "run the tools with no issues", and for the two machines where the tools return the error, that would be helpful.

    Also, details about your tools (custom module, code for MRR menus, stand alone applications, etc.) as well as how they are configured would be helpful.

    You might want to take a look at some of the sample code I posted here:  https://github.com/DanWilliamsAtBentleyDotCom 

    and take a look on how I have then configured for the debug build (I didn't bother making sure that any "release" build was configured properly).  For example, here's how I have a build configured for use by an MRR file:

    At least this is my best guess for now based upon what I can infer from your post!  : -)

Children
  • Thanks for the response, Dan. 

    I kept digging and think I found the problem, though I don't understand it.

    While we do have both 32- and 64-bit custom modules applications, those weren't the issue.  I actually installed them on one of the failing machines and they worked fine. The two are the same project, one built with 32-bit and used with ProjectWise Explorer and one built as 64-bit and used with integrated applications.  There is an "AnyCPU" C# DLL that handles the API calls that these both use.  The applications at issue are separate VB.Net and C# executables.  These are built as AnyCPU and link in that same supporting library.  That library is the one where the failure occurs calling into the API for these separate applications.  I've installed the custom modules on the machines where the batch applications are failing, and they work okay.  As part of my investigations, I was making certain the PATH had the X86 PWBIN folder, which we need for these custom modules.

    All of the machines that run these stand-alone applications are Windows 10 64-bit machines.  They are supposed to be basically clones of each other, though they can differ in some other software that is installed for other uses.  I tried rebuilding one of the applications as 64-bit with all of the supporting libraries as AnyCPU.  It had the same result on the machines; where it worked on one where the AnyCPU version worked and failed on one where the AnyCPU failed.

    What I eventually found was that on the working machines, the PATH Environment Variable had both the "C:\Program Files (x86)\Bentley\ProjectWise\Bin\" folder and the "C:\Program Files\Bentley\ProjectWise\Bin\", with the X86 version coming first.  On the failing machines, PATH had X86 version, but not the X64 version; even though the X64 folder also existed.  I did know that if both are in the PATH, we're supposed to make certain the X86 is listed first.  I was not aware that the X64 needed to be there, at all.

    Thanks for your help.  If you can explain why this happens, I'd love to make sense of it.

  • I'm not sure exactly what you are asking.  Assuming you are asking why do both folders need to be in the PATH environment variable, well, that's because of the way "Windows" finds a dll to load.  It first looks in the same folder (directory) as the calling program is in, and if it can't find it there, it looks in each of the directories in the PATH variable until it finds it, or until there is no more directories to search.

    You can program your way around this problem (not having those directories in your PATH variable), by doing what Dave Brumbaugh does in his MostOfDavesClasses.cs, i.e. search the registry for where those directories are located (ProjectWise could be installed on a different drive/path than the default), and then add it to the PATH variable (which stays there only for the duration of the process).

    Here's what his code looks like (when the first call to PWWrapper occurs):

    And this:

    And then this:

    Then you don't have to worry how the user's machine PATH variable is configured!

  • Here's what I don't understand.  When the machine has only the X86 ProjectWise bin folder in the Path, running the executable fails trying to load one of its libraries.  This would seem to imply that that is the wrong version of the library in that instance.  But, if you add the X64 version in that Path AFTER the X86, then when that same application searches the Path for the matching library, shouldn't it find the X86 version first, and still fail?  It's always seemed like this would be a problem for Windows supporting both X86 and X64 versions of an application simultaneously; one of them would have to fail depending on the Path order.  Since appending the X64 folder to the Path fixes the issue, that is clearly not the case; I just don't understand why.

    Our custom modules have always worked with just the X86 ProjectWise bin folder in the Path.  I took that to mean that, somehow, the X86 versions were being used for both ProjectWise Explorer and the integrated applications.  I take it the integrated applications are actually adding the X64 to that Path on the fly, as your example of Dave's code shows. 

    Thanks for your help, Dan.

  • If I understand your last question, MostOfDavesClasses.cs is looking to see if the current process is 32 or 64 bit so that the "right" path is appended.  If you are creating code that this called by ProjectWise Explorer, they you are pretty much locked into 32-bit code.  If you are running your own application, then Dave's code is determining if it is 32 or 64 bit so that the "right" path is appended.  I don't believe (I could be wrong!), that Dave's' code appends both paths, just the one "in context" of the first call and only if that first call, the initial loading of the DLL, fails.

    When you say "integrated applications", that's a bit confusing to me as I have trouble understanding my native (and only) language!  I often say "words get in the way".  So, there's "integrated" in the sense of things like MicroStation/ProjectWise, etc. where ProjectWise Explorer (32-bit) and MicroStation (64-bit) exchange information and "work" together, vs. "integrated application" in the sense of a ProjectWise "Customer Module" that works with ProjectWise Explorer, both 32-bit, etc.

    Part of the "Path" problem is that on 32-bit machines, there is just (typically) C:\Program Files\... and the programs are all 32-bit, while on a 64-bit machine, C:\Program File\... are where the 64-bit versions are, while the 32-bit versions are (typically) under C:\Program File (x86), except when they are not!

    You may have to refactor you appliciations so that they know how to "behave" under the various configurations.

  • Okay, I'll try to be a bit more specific.

    We have a few .exe files that are built as "AnyCPU".  Running on a Windows 10 64-bit machine, these call into a .dll file that is also built as "AnyCPU".  This .dll file will call into, for example, the dmscli.dll file.  On that Windows 10 64-bit machine, both the X86 and the X64 versions of ProjectWise are installed.  This machine has had only the X86 version of the ProjectWise bin folder is in the Path, and when that is the case that executable fails with the "Incorrect Format" error.  This makes sense because it means that the executable and the AnyCPU library are both running as 64-bit, and are attempting to load the 32-bit version of the dmscli.dll file because that is version found in the Path.

    When I append the x64 version of the ProjectWise bin folder into the Path, so that x86 and x64 are both in the Path, but the x86 version comes first, the application runs okay.  What I do not understand is why Windows doesn't find the x86 version first (since it precedes the x64 folder in the Path EV), attempts to load it, and fails with the same error.

    I do understand that there are two different builds of the PW libraries and you need to make sure you're loading the right one based on how what environment the application is running under.  I have some other questions, but I don't want to distract from the one I high-lighted above. 

    Thanks, again.