Alessandro Ciurlo
Alessandro Ciurlo

Reputation: 122

.NET Framework (v 4.0) COM Registration free called from Win32 C++ application

I need to create a registration free COM object in .Net Framework using C#.

I've followed the MSDN walkthrough. I've to work on it because, or it is not enough clear to me, or it is not correct, however this is an old post and I use Visual Studio 2015 on Windows 10, so maybe something is changed.

Here in the following the steps that I've made to make it work:

  1. Compile COM C# dll SideBySide.dll (Target Framework 2.0), of course I've not registered it by regasm.

  2. I don't use the approach described in the tutorial, it seems not work for me. I create SideBySide.Manifest by mt.exe, here's the command:

    mt -outputresource:"<path SidebySide.dll>" -manifest "<SideBySide.manifest>"

  3. I've manually modified the generated manifest to remove all not useful tags, and add the mandatory ones. Here is the modified manifest:

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity
            name="SideBySide"
            version="1.0.0.0"
            type="win32" />
        <clrClass
            clsid="{4B72FC46-C543-4101-80DB-7777848D1357}"
            progid="SideBySide.SideBySideClass"
            threadingModel="Both"
            name="SideBySide.SideBySideClass"
            runtimeVersion="v2.0.50727">
        </clrClass>
        <file name="SideBySide.dll">
        </file>
    </assembly>
    
  4. I've added the manifest to SideBySide.dll with this command:

    mt -outputresource:"<Path SidebySide.dll>" -manifest "SideBySide.manifest"

  5. I've exported the TLB from SideBySide.dll using tlbexp`.

  6. I've set No in the configuration Properties -> Manifest tool -> Embed Manifest of the C++ client.

  7. I've compiled client.exe, and then I've applied changes to the client.exe.manifest file. Here is the modified manifest:

    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <assemblyIdentity
            type = "win32"
            name = "client"
            version = "1.0.0.0" />
        <dependency>
            <dependentAssembly>
                <assemblyIdentity
                    type="win32"
                    name="SideBySide"
                    version="1.0.0.0" />
            </dependentAssembly>
        </dependency>
    </assembly>
    

Everything is working well, and it seems that I can consume the .Net Framework COM interface from the native C++ application.

However, there is an issue when I try to compile SideBySide.dll with .Net Framework 4.0 or newer, when I call CreateInstance:

ISideBySideClassPtr ptr;
HRESULT hr = ptr.CreateInstance(__uuidof(SideBySideClass));

This error occurs:

0x8013101b : This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

Of course, I've tried to perform all the steps listed above, I try also to specify the runtime version in the manifest of the DLL, but it was not useful.

I also read this post. The problem is the same, but the solution, in my opinion, is not suitable for me, because I need to call a C# COM object from a native client.

Is there some workaround to apply, or do I need another approach to my problem?

Upvotes: 1

Views: 872

Answers (2)

0909EM
0909EM

Reputation: 5027

I appreciate this a little late, but for anyone else that comes across this...

I had this problem earlier today. My Registration Free COM library is built with .Net 4.5.2, my solution was to use the "runtimeVersion" attribute as follows

<clrClass 
   clsid="{...}" 
   progid="Library.Name" 
   threadingModel="Both" 
   name="Library.Name.Class"
   runtimeVersion="v4.0.30319">

Alternatively, you can leave out the runtimeVersion attribute (or specify v2.0.50272) and compile your library for .Net 3.5. Either solution appears to resolve the issue.

Upvotes: 3

Joseph Willcoxson
Joseph Willcoxson

Reputation: 6040

I am only guessing, but you say that the runtime version is 2.0.50727 in your manifest file, but you are having trouble compiling with 4? You have a mismatch in version with your manifest and your tools.

I just use the manifest tool to create and store the information in my assembly (in PostBuild step):

"$(PathToYourTools)\mt.exe" -managedassemblyname:$(TargetPath) -nodependency -outputresource:$(TargetPath);#2

It has the added benefit of not requiring to generate the typelib for the .NET assembly.

Upvotes: 0

Related Questions