none
PInvoke restriction: cannot return variants RRS feed

  • Question

  • Greetings,

    I have written an console application that would backup some ComApplications properties using the methods available in ComAdmin.dll.

    So, i have added a reference of this dll to my console application. So, this would require the dll at runtime too (i.e. while the exe is running). But, i dont want to copy this dll all time with the console exe.

    So, i just thought of using DllImport to import all the required methods and start using them in my console application. But, i get this "PInvoke restriction: cannot return variants." . I understand this is an restriction and i would like to know, do we have any ways to overcome this.

    Is this possible to achieve my goal using DllImport with any workarounds ?

    I tried to explore the ComAdmin.dll in reflector and copy the classes and Interface code into my console application - with this, i was able to execute the first two line successfully.

       COMAdminCatalog comAdminobj = new COMAdminCatalog();
       COMAdminCatalogCollection collection = ((COMAdminCatalogCollection)comAdminobj.GetCollection("Applications"));
       collection.Populate();
       return collection;

    But, it failed with system invalidoperationexception while populating the collection, without much information. Has anyone come across this kind of problem?

    Please do share your valuable inputs for achieving the requirement.

    Thanks and Regards,

    Sathyanarayanan

    Tuesday, October 26, 2010 10:04 AM

All replies

  • Hi,

    Thanks for your post. I am not sure about what your scenario is. But based on your description, the ComAdmin.dll is a COM DLL. The COM methods it provides cannot be used in a P/Invoke way. As to the error message you got, please take a look at this similar thread.

    The COM dll could be used through an interop assembly. In order to execute the 4 lines of code you provided, I add reference to the ComAdmin.dll in my C# project and the code runs fine. Please correct me if I mis-understood you.

    The code I tested is like this:

     static void Main(string[] args)
     {
      COMAdminCatalog comAdminobj = new COMAdminCatalog();
      COMAdminCatalogCollection collection = ((COMAdminCatalogCollection)comAdminobj.GetCollection("Applications"));
      collection.Populate();
      Console.WriteLine(collection.Count);
     }
    
    

    Please mark the right answer at the right time.
    Thanks,
    Sam
    • Edited by SamAgain Friday, October 29, 2010 9:04 AM refine
    Friday, October 29, 2010 9:04 AM
  • Hi Sam,

    Thanks for your reply.

    I guess Sathyanarayanan is wishing to execute those piece of code without including the reference in the C# project.

    I too have a similar scenario as explained above. We just need to make this code work without the reference of this com Dll. Similar like DllImport (i know this cant be done here due to PInvoke restriction). This requirement is just to avoid the physical presence of the ComAdmin.dll with the final exe.

    Please let us know, if there are any alternative ways of achieving it.

    Regards,

    Yathish

     

     

    Tuesday, November 2, 2010 10:30 AM
  • Hi,

    Thanks for your valuable feedback. Just a quick reflection. A COM dll also exports some well known functions such as CoGetClassObject(), we could use LoadLibrary() to load the dll and use those well konwn methods as a startpoint, they will lead us to the inside COM types. This is basically how the COM runtime could reach the internal coclass contained in a COM DLL. Also we need to use pinvoke to call the CoInitialize() function to initialize the COM runtime.


    Please mark the right answer at the right time.
    Thanks,
    Sam
    Friday, November 5, 2010 11:33 AM