Facing issue in using a COM library

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
Hello All
I have a C# project developed in dotnet framework 4.5 , windows 10 machine. The project "adds a reference" to the COM library , that has been developed in VB6
The project compiles properly but when it is run , I get the exception as below


C#:
System.TypeInitializationException:
'The type initializer for 'CcWanPipesClientLib.ClearcaseHelper' threw an exception.'

innerexception:
BadImageFormatException: Retrieving the COM class factory for component with CLSID {B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F} failed due to the following error: 800700c1  is not a valid Win32 application. (Exception from HRESULT: 0x800700C1).

On different links and forums , dllsurrogate method " Using a 32bit COM object in a 64bit environment" , I followed the same
But still the exception comes.

Please guide me through it as I am new to both C# and COM
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
And worse case, compile your code to target 32-bit instead of 64-bit. Why pay the price of thunking from 64-bit down to 32-bit when you don't need to.
 

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
I ported the VB6 code to C++ and am able to create and register the COM dll in 64 bit . But I am still facing the same issue . Any insights would be of great help
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
Sounds like a bug in the way you are registering your COM object. This is not a C# problem.

Anyway, post your your COM registration code. It looks like your may not be pointing to your COM DLL properly.

And be sure to post the error again. Is it the same exact error, or some other error?

As an aside, if your took time to to port the VB6 code to C++, why not go the extra step to use C++/CLI and IJW?
 

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
I have attached a gif file and a png file . The gif file displays the COM library that has been referenced by a C# Code ( CCAutomation ). The CCAutomation creates a wrapper API over the COM . The API has been called in another C# project where the exception is thrown ( exception is in png file )
Exception:
 

Attachments

  • vsissue_exception.PNG
    vsissue_exception.PNG
    32.7 KB · Views: 1

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
Please share some insights or links towards C++/CLI and IJW. I can look into the same
 

Attachments

  • vssiue.mp4
    1.8 MB · Views: 0

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
No. Don't send screenshots of code. Post the code as text in code tags.
 

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
Exception:
System.TypeInitializationException:
'The type initializer for 'CcWanPipesClientLib.ClearcaseHelper' threw an exception.'

innerexception:
BadImageFormatException: Retrieving the COM class factory for component with CLSID {B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F} failed due to the following error: 800700c1  is not a valid Win32 application. (Exception from HRESULT: 0x800700C1).

Exception has been shared
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
Thank you, and now the code that writes to the registry to register your COM object?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
The video you showed on post #7 shows how you are adding a reference to the COM library. That is not how what I'm asking about. I'm asking about how the COM library is registered on the machine.

In post #4, you said that you re-wrote the VB6 code to C++. What does the C++ code look like? Specifically, what does the DllRegisterServer() look like for the COM object?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
Not directly related to your problem, but recall that .NET Framework 4.5 is out of support. You need at least 4.6.2 to still be in support by Microsoft.
 

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
The C++ code is now a copyright code for my company , still I have added the "Dllregisterserver" part here
C#:
STDAPI DllRegisterServer(void)
{
    // registers object, typelib and all interfaces in typelib
    HRESULT res = _Module.RegisterServer(FALSE);
    if (FAILED(res))
        return res;

    TCHAR filename[_MAX_PATH];
    GetModuleFileName(_Module.m_hInstResource, filename, _MAX_PATH);

    USES_CONVERSION;
    CalBSTR bfilename(T2OLE(filename));

    CComPtr<ITypeLib> pTypelib;

    res = LoadTypeLib(bfilename, &pTypelib);
    if (FAILED(res))
        return res;

    return RegisterTypeLib(pTypelib, bfilename, 0);
}
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
That is still opaque to us, since we can't see how _Module.RegisterServer(FALSE) works.
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
Let's try a different approach. Export the subkey for your COM object's CLSID into .REG file, then post the contents of the .REG file in code tags here.
 

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
_Module.RegisterServer:
inline HRESULT CComModule::RegisterServer(
    _In_ BOOL bRegTypeLib /*= FALSE*/,
    _In_opt_ const CLSID* pCLSID /*= NULL*/) throw()
{
    HRESULT hr = S_OK;
    _ATL_OBJMAP_ENTRY* pEntry = m_pObjMap;
    if (pEntry != NULL)
    {
        for (;pEntry->pclsid != NULL; pEntry++)
        {
            if (pCLSID != NULL)
            {
                if (!IsEqualGUID(*pCLSID, *pEntry->pclsid))
                    continue;
            }
            hr = pEntry->pfnUpdateRegistry(TRUE);
            if (FAILED(hr))
                break;
            hr = AtlRegisterClassCategoriesHelper( *pEntry->pclsid,
                pEntry->pfnGetCategoryMap(), TRUE );
            if (FAILED(hr))
                break;
        }
    }
    if (SUCCEEDED(hr))
        hr = CAtlModuleT<CComModule>::RegisterServer(bRegTypeLib, pCLSID);
    return hr;
}
 

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
Command: >reg export "HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}" "ccauto32_32.reg" /reg:32
32bit:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}]
@="B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F"
"AppID"="B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F"

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}\InprocServer32]
@="C:\\Program Files\\IBM\\RationalSDLC\\clearcase\\bin\\ccauto.dll"

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}\ProgID]
@=""

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}\VersionIndependentProgID]
@=""



Command : reg export "HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}" "ccauto32_64.reg" /reg:64
64bit:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}]
@="ClearCase Class"

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}\InprocServer32]
@="C:\\Program Files\\IBM\\RationalSDLC\\clearcase\\bin\\ccauto.dll"
"ThreadingModel"="Both"

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}\ProgID]
@="ClearCase.Application.1"

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}\Programmable]

[HKEY_CLASSES_ROOT\CLSID\{B22C7EFB-5A5E-11D3-B1CD-00C04F8ECE2F}\VersionIndependentProgID]
@="ClearCase.Application"
 
Last edited:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
I thought that you were now building your COM object as 64-bit. Why are you still registering it as 32-bit?
 

kamleshm

Member
Joined
Nov 18, 2021
Messages
10
Programming Experience
5-10
The crux part is if I create a console application and add the COM library as a reference, it works as expected . But in my case I have a wanservice.dll that refers to the COM dll and thats the place where the exception comes . Also while building the code , I get few Metasource code ( C# files ) . Its different for a console application and a dll
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
4,027
Location
Chesapeake, VA
Programming Experience
10+
Is the running console application running as 32-bit or 64-bit? Compile your C# program to run with that same bit width. Abandon trying to use the DllSurrogate since you don't have to. You have the ability to compile against the bit width that you want to use. The error that you are getting ( 0x800700c1) is saying that it's not recognizing "C:\Program Files\IBM\RationalSDLC\clearcase\bin\ccauto.dll" as binary that it can load. That normally happens when the DLL is of the wrong bit width for the process that is trying to load the DLL.
 
Top Bottom