Please help with my 3rd party Primary Interop Assembly issue RRS feed

  • Question

  • I am trying to interface a .NET program with a Primary Interop Assembly provided by a third party for COM access to their software. The PIA interface, as visible from .NET, is rather ugly (in .NET terms), especially from C#: cases of get_XXX/set_XXX not being translated to properties, several places where "VB optional" arguments come across as required "ref" parameters, class/interface naming confusion, and so on. I coded a VB.NET wrapper around the PIA COM wrapper, to make it prettier for my C# code, but can't get it to work due to what I believe to be a "CopyLocal conflict": my .NET wrapper needs CopyLocal to be true, but my wrapper's PIA COM reference CopyLocal should be false.

    I can access the PIA directly (i.e., with a direct reference to the PIA, with CopyLocal set to false). However, I cannot access the .NET wrapper without errors. I either get a version conflict with the .NET reference's CopyLocal set to true (manifesting as an invalid cast exception) or I get a file not found exception with CopyLocal set to false. The vendor says the PIA must remain in their application's Bin directory, and that such auxiliary apps as ours should be placed in that directory, but that is sub-optimal for many reasons. The vendor's installer makes the appropriate registry entries (such as \HKROOT\CLSID\<GUID>\InprocServer32\<version>\CodeBase = "file:///c:/Program Files..."). In short, the application and its PIAs should be set up correctly; I just need to find a way to tell my wrapper (VB.NET library) that it needs to be CopyLocal-ed, but the PIA does NOT need CopyLocal-ed.

    I suspect the solution lies with an appropriate app.config, but I have no idea how to create one; all the information I can find on that just relates to direct dependency references, not this indirect situation I'm facing.

    Any advice is appreciated. Thank you in advance.

    • Edited by Hywyred Wednesday, June 15, 2011 3:09 PM double-break paragraphs
    Wednesday, June 15, 2011 3:07 PM

All replies

  • Hi Hywyred,

    Welcome to the MSDN forum.

    According to your description, I think we can only set CopyLocal property in the project and control to do or not copy the referenced dll to local directory. We can not control the copylocal property of PIA which is provided by a third party assembly. I think you may have to discuss it with vendors.

    Have a nice day!

    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, June 17, 2011 10:11 AM
  • Hi Paul,

    Thank you for that information.  I guess I'll have to find an alternative.  I doubt the vendor will be helpful with this issue.  Is there a way to avoid the whole CopyLocal thing?  I found some information about specifying dependencies using app.config instead of project references, but I still can't figure out how to tell the runtime that I want the same PIA reference used by both my class library and my console exe.

    Still, I would like to verify that my suspicions about PIA loading conflicts are the culprit.  In the VS 2008 Output window (showing Debug output) only shows the PIA being loaded once.  (Maybe there is some sort of "virtual reloading" of the PIA taking place when my class library is loaded?  If so, how would I avoid that?)

    Let me back up a bit, because perhaps my approach is wrong.  What I really want to do is to exploit the COM-friendliness of VB.NET in my C# project.  Now, I can't mix languages within the same project, so what are my options?  The class library was the easiest, but with this PIA issue doesn't seem viable.  Instead of using a class library, could I perhaps use a multi-file assembly, as described here and here?  It seems to me that it should.

    The MSDN documentation only describes using the command line for building a multi-file assembly.  Is there any way to coerce Visual Studio into building it for me?  Putting my PIA wrapper into a class library is really the best approach, since I intend to use the library across some other projects as well; if I can only include this as a multi-file assembly, it is really going to increase the complexity of my build.


    Friday, June 17, 2011 1:50 PM
  • Hi again,

    Further testing has revealed what appears to be an inconsistency between the VB and C# handling of COM interop, rather than with the routing of the interop calls.  I tried using the multi-file assembly, and failed with the same InvalidCastException I saw before.  What if the problem is C# + COM vs. VB + COM?  So I created a VB project, referenced my PIA wrapper library, and gave it a shot.  No problems, but not at all what I expected.

    So I went back to the InvalidCastException.  I realized there are some calls that aren't as atomic as I believed.  The COM library's architecture is pretty standard as far as I can tell:  There is only one object that can be directly created, a Login object.  Its class contains a Logon method which takes a userId and password and returns an Application object (which functions as the root of the rest of the COM hierarchy).  The Login object also has an ActiveApplication property, which seems to be the same as what is returned from the Logon method (after its called).  I refactored my wrapper library a little bit to separate the call to the Logon method from the assignment to the Application member.  To my surprise, it is the call to the Logon method that is throwing an InvalidCast, not the return value assignment!

    That puzzled me for a moment until I realized that it actually fits with my hypothesis about a VB/C# COM Interop inconsistency.  My best guess is that there are some hidden, auto-generated classes floating around on the .NET side to facilitate marshaling.  Further, I think there are separate auto-generated classes on the VB side as on the C# side.  And they are not compatible, not all at once.

    Is cross-language development with COM Interop just a bad idea, or is its handling just buggy?

    It looks like I'll have to change my VB wrapper to a C# wrapper, which is just going to be nasty.

    Further advice would be appreciated.


    Friday, June 17, 2011 4:43 PM