Registration free com dll asks for .net framework 3.5 installation while it is working fine when registered

2

I have a COM DLL written in c#. I have tried registering it and it works fine. I am trying to use it registration free.

I followed this MSDN tutorial exactly.

The SideBySide DLL source:

using System;
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: Guid("C49B4D72-DEB3-41F3-87DE-9AA0E0E99809")] //LIBID_SideBySide

namespace SideBySide
{
    [Guid("1289C276-6CF8-456F-9CD3-14363BA5BEB5")] //IID_ISideBySideClass
    public interface ISideBySideClass
    {
        string Version();
    }

    [Guid("16AD5303-E154-44B4-A72B-C129859714AD")]  //CLSID_SideBySideClass
    public class SideBySideClass : ISideBySideClass
    {
        public string Version()
        {
            return "1.0.0-C#";
        }
    }
}

SideBySide.manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
  manifestVersion="1.0">
<assemblyIdentity
            type="win32"
            name="SideBySide"
            version="1.0.0.0" />
<clrClass
            clsid="{16AD5303-E154-44B4-A72B-C129859714AD}"
            progid="SideBySide.SideBySide"
            threadingModel="Both"
            name="SideBySide.SideBySideClass" >
</clrClass>
</assembly>

Application manifest Client.exe.manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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>

Usage:

Method1 is the way the tutorial suggests to use the DLL. I have explored and came up with the method2 which uses activation context.

Method1:

/*
Using CreateInstance
*/
int method1()
{
    CoInitializeEx(0, COINIT_MULTITHREADED);
    ISideBySideClassPtr ptr;
    HRESULT hr = ptr.CreateInstance(__uuidof(SideBySideClass));
    if (SUCCEEDED(hr))
    {
        cout << ptr->Version() << endl;
    }
    else 
    {
        //The dialog box asking for .net framework 3.5 installation comes up here
    }
    CoUninitialize();
    return 1;
}

Method2:

/*
Using Activation context
*/
int method2()
{
    HRESULT _hr = CoInitializeEx(0, COINIT_MULTITHREADED);
    if( _hr != S_OK)
    {
        return FALSE;
    }

    DWORD cookie = 0;

    ACTCTX actctx;
    actctx.cbSize = sizeof(ACTCTX) ;
    actctx.lpSource = L"SideBySide.dll";
    actctx.lpResourceName = //_T("SideBySide"); //error
        MAKEINTRESOURCE(1); //This alone worked for CreateActCtx
        //MAKEINTRESOURCE(2); //error
    actctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID ;

    HANDLE hActCtx = CreateActCtx(&actctx);
    if( hActCtx == INVALID_HANDLE_VALUE)
    {
        //This usually fails here.
        //But with the above mentioned values this succeeds
        return E_FAIL;
    }

    BOOL fOK = ActivateActCtx(hActCtx, &cookie);
    if (!fOK)
    {   
        return E_FAIL;
    }

    CComPtr<ISideBySideClass> spCSharpTest;
    HRESULT hr = spCSharpTest.CoCreateInstance(__uuidof(SideBySideClass));

    if (hr != S_OK)
    {
        //The dialog box asking for .net framework 3.5 installation comes up here
    }
    else
    {
        cout << "Load Successfully : SideBySideClass" << endl;
        spCSharpTest->Version();
        //Need not release. CComPtr will take care of it
    }

    DeactivateActCtx(0, cookie);
    ReleaseActCtx(hActCtx);
    CoUninitialize();
    return 0;
}

Problem:

Both of these methods fail when I try to create an instance of the class and gives the following error 0x80131700 (2148734720) (doesn't have a description), then I get the following dialog box prompting installation of .net framework 3.5: enter image description here

I have specified "Target framework" in Properties->Application of SideBySide C# project as .NET framework 4.5 and it works perfectly when the com dll is registered. I do not understand why it asks for an older version when trying to use without registration.

Should I specify the .net framework version anywhere in the manifest files? What could be the problem? Any help would be highly appreciated.

c#
.net
windows
dll
com
asked on Stack Overflow Jul 31, 2017 by Shameel Mohamed

1 Answer

2

Yes, you'll need to specify the runtime version when using .NET 4.0 or higher. If this information is missing in the server manifest, the activation context will look for the highest runtime version available prior to .NET 4.0, i.e. version 3.5.

Simply add the required .NET runtime version as follows (note the runtimeVersion attribute):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
  manifestVersion="1.0">
<assemblyIdentity
            type="win32"
            name="SideBySide"
            version="1.0.0.0" />
<clrClass
            clsid="{16AD5303-E154-44B4-A72B-C129859714AD}"
            progid="SideBySide.SideBySide"
            threadingModel="Both"
            name="SideBySide.SideBySideClass"
            runtimeVersion="v4.0.30319" >
</clrClass>
</assembly>
answered on Stack Overflow Jul 31, 2017 by Aurora

User contributions licensed under CC BY-SA 3.0