none
A com addin works in F# but not in C# RRS feed

  • Question

  • Hello,

    Has anyone ever come across a problem where a COM addin would be usable in F# code but not in C#?

    I have a COM addin that I load into F# using System.Activator.CreateInstance(Type.GetTypeFromProgID(AddinName)),

    where AddinName is the string containing the name of the COM addin. In F#, this call returns an object which is of type System._ComObject, but the same is not working in C# where I get a run-time System.IO.FileNotFoundException.

    I have verified that the two projects reference the same dll and have the same build and debug settings.

    Thanks,

    Elena

    Wednesday, July 2, 2014 8:33 PM

Answers

  • Hi Elena

    I've had a few "FileNotFound" problems in the past and finding out which file is not being found usually helps solve the problem. I'm not sure how much help this would be but here are 2 options that might help narrow the problem down.

    Firstly - trying using the Fuson Log Viewer, it ships with Visual Studio and will give you detailed information on where the .Net runtime looks when trying to load files. My only doubt here is that I'm not sure how much of the COM instantiation will go through the .Net runtime (probably not much), but it's worth a try. Just to state the obvious: you need to enable the logging before you view the details, it's not enabled by default.

    Secondly - try using the Process Monitor tool from SysInternals. It'll monitor all of the file reads happening on your system. You'll just have to adjust the filtering as it includes a lot of information by default. I've had mixed results using this option, there are usually so many file reads and so many not  found errors (that aren't really a problem) that it can be hard to find the real cause.

    Hopefully one of those options helps to narrow down the problem at least. Failing that it might be worth trying WinDbg, but that's probably best left as a last resort :)

    Just one last thing - I noticed in your example you mention "DLLNAME", I assume you're using a ProgId and not the name of the file?

    Good luck,

    Greg

    • Marked as answer by igra101 Friday, July 4, 2014 10:55 AM
    Friday, July 4, 2014 7:03 AM

All replies

  • Hi Elena,

    I assume there is something wrong with the code. It’s better if you can post some code to help reproduce.

    I found an article about a similar question, please refer to see more information. http://bytes.com/topic/c-sharp/answers/273488-dynamically-create-com-objects-c.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, July 3, 2014 9:37 AM
    Moderator
  • Hello,

    Thank you for your reply. The article that you shared makes a valid point - why create a dynamic assembly object when one can just be referenced directly in the project. I will try this instead.

    However, it would be nice to understand the reason for the behaviour my original question was on.

    The code in F# is simply:

    let test = System.Activator.CreateInstance(Type.GetTypeFromProgID("DDLNAME"))

    The above works in F# and test is a com object.

    I believe the equivalent in C# should be as below, which does not work and terminates with System.IO.FileNotFoundException:Retrieving the COM class factory for component failed due to the following error: 80070002.

    var test = System.Activator.CreateInstance(Type.GetTypeFromProgID("DDLNAME"));

    Regards

    Thursday, July 3, 2014 9:54 AM
  • Hi Elena

    I've had a few "FileNotFound" problems in the past and finding out which file is not being found usually helps solve the problem. I'm not sure how much help this would be but here are 2 options that might help narrow the problem down.

    Firstly - trying using the Fuson Log Viewer, it ships with Visual Studio and will give you detailed information on where the .Net runtime looks when trying to load files. My only doubt here is that I'm not sure how much of the COM instantiation will go through the .Net runtime (probably not much), but it's worth a try. Just to state the obvious: you need to enable the logging before you view the details, it's not enabled by default.

    Secondly - try using the Process Monitor tool from SysInternals. It'll monitor all of the file reads happening on your system. You'll just have to adjust the filtering as it includes a lot of information by default. I've had mixed results using this option, there are usually so many file reads and so many not  found errors (that aren't really a problem) that it can be hard to find the real cause.

    Hopefully one of those options helps to narrow down the problem at least. Failing that it might be worth trying WinDbg, but that's probably best left as a last resort :)

    Just one last thing - I noticed in your example you mention "DLLNAME", I assume you're using a ProgId and not the name of the file?

    Good luck,

    Greg

    • Marked as answer by igra101 Friday, July 4, 2014 10:55 AM
    Friday, July 4, 2014 7:03 AM
  • Hi Greg,

    Thank you very much for your suggestions.

    I will start with the FusLogVW.

    Regards,

    Elena

    P.S. Yes, the DLLNAME contains the ProgID.

    Friday, July 4, 2014 10:55 AM
  • This is an update to the solution, which took me a while to find.

    Some dlls written in F# will implicitly have a dependency on the FSharp.Core.dll version (e.g. 2.0, 4.0, etc.)

    It appears that an C# project (at least in VS 2010), will attempt to create redirects to newer version of dlls, where they exhist.

    This is visible in the app.config file which is located in the project root directory. So, entries like below can be seen in this file:

    <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>

    The redirect happens automatically, but you may get a warning message on the assembly version conflict.

    If you are working with a dll that depends on the older versions of F#, and the runtime has created such redirect, then you will run into the same problem, where something works in F#, but does not work in C#.

    The solution is to either upgrade the dll to use the latest F#, or manually modify the app.config file in the C# project.

    As the previous replies have suggested, the way to pin down this problem is by studying the logs from FusLowVW.exe.

    Hope this saves someone days of debugging!

    Elena


    • Edited by igra101 Tuesday, July 8, 2014 9:51 AM
    Monday, July 7, 2014 7:49 AM