Question

When I try to Convert HTML to XHTML Tag I'm getting the following error...

Error: Retrieving the COM class factory for component with CLSID {59939390-0E6A-4F1B-A742-20C5459501F7} failed due to the following error: 80040154.

After googling I found few solutions:

Registering the DLL into regsvr32 "E:Source Code\bin\Interop.HTML2XHTMLLib.dll"

I'm just tried to register the dll. But E:Source Code\bin\Interop.HTML2XHTMLLib.dll was loaded. But the DllRegisterServer entry point was not found this error message was displayed. Why..?

Recompiled my project for x86 and x64.. no use..

VB.NET Code:

Dim xhtmlUtil As New XHTMLUtilities // Here itself im getting the above error.

sFormattedOutput = xhtmlUtil.convertToXHTML(sInputline) //Send it for conversion

My Operating system is Windows XP 32-bit Service pack 3. My application was done in VS2008. currently I'm working with VS2010.

Here what I'm missing. Could any one help me to figure out this problem?

Thanks in advance.

Était-ce utile?

La solution

i'm just tried to register the dll. But E:Source Code\bin\Interop.HTML2XHTMLLib.dll was loaded. But the DllRegisterServer entry point was not found this error message was displayed. why?

The Interop.HTML2XHTMLLib.dll file isn't the library you want to register using regsvr32. It is only the managed interop assembly, generated make COM objects accessable for your .NET application. You actually need to register the type library for the HTML2XHTMLLib.dll.

To do this, you have two options:

  1. Find the redistributeable package, that contains the library and install it together with your application.
  2. On your development system, open the "Add references" dialog of Visual Studio. Choose the COM tab and search for the library (just like you did when you've added the reference). There you will find the absolute path to the library. Copy the library to the client system and register it using regsvr32.

Since I do not know the source of the HTML2XHTMLLib, I can only suggest those ways. You should prefer the first one.

Since you've started a bounty on this, I want to go a little bit more into detail on COM and the InterOp.

Differences between COM and .NET assemblies

There are two types of servers in COM: InProc-servers and OutProc-servers. InProc (In Process) are servers we usually know als DLL. OutProc (Out of Process) servers are standing alone, running in their own process. We know them as EXEcutables.

You want to consume an InProc-server. Your COM-server (HTML2XHTMLLib) consists out of two parts:

  1. A type library (.tlb), that contains meta-information about the server, it's contained objects and their accessability.
  2. A library, containing the code where all the objects are implemented. The library also exports the following static functions:
    • DllGetClassObject – Tries to create an instance of an object, defined inside the server
    • DllCanUnloadNow – Tells the COM environment, whether or not the server can be released, because it isn't used by any other process any more.
    • DllRegisterServer – Called by regsvr32 to register the previously mentioned type library in the Windows Registry, to make it visible to clients and the COM environment.
    • DllUnregisterServer – Does the exact opposite, when called through regsvr32 -u.

The type library can also a resource of the DLL or EXE file, so that there's only one file. For C# developers this seems somehow confusing, since meta-information is directly compiled into a.NET assembly and accessable through reflection.

The InterOp: A wrapper between .NET and COM

So basicly type libraries describe everything that is needed by the .NET reflection to access the objects exposed through COM. But the problem is, that COM-components are stored in a different format:

  • Usually they are directly compiled into machine code: You cannot link a .NET assembly, compiled with AnyCPU against a COM-server. COM-servers are directly compiled to either x86-assembler, or x86-64-assembler. They have fixed pointer sizes and thus are only compatible with one of the compilation-models.
  • COM defines rules for memory management. Each COM-object must implement the IUnknown-interface. This interface defines three methods. The methods AddRef and Release are for memory management purposes. Whenever a client accesses an COM object it needs to call AddRef. This increases a counter by one. When the client does not need the object anymore, it calls Release instead of deleting the object, resulting in a counter decrement. If the pointer reaches 0, the object delete's itself. This is different from how .NET manages memory. In .NET the garbage collector visits each object on the heap in a non-deterministic manner (you cannot determinate the exact point of time an object get's deleted) and releases the object, when there are no references left to it.
  • COM defines rules for identity. Whenever you only want to access an base interface of an object, you have to call the QueryInterface method, defined by IUnknown. This method is guaranteed to allways return the same pointer, when a specific interface get's queried. This might be also true for .NET (besides you are overloading some operators), but the way .NET ensures object identity is different.
  • COM defines rules for object relations. Crazy stuff like Aggregation and Containment, which do also exist in .NET, but are implemented differently.
  • COM defines different multithreading rules, like Single Threaded Appartments and Multi Threaded Appartments. Those threading models define how objects interact, when they are coexisting in different manners. In .NET you have to perform each synchronisation process manually.

This list may not be complete, neither I want to go into detail any further, because it is only incidental for your question, but you see, that there are some big differences between .NET and COM. And to manage those differences there is a layer between both worlds: the COM InterOp.

If you are calling a COM server from .NET, the InterOp is nothing more than a .NET assembly, that does all the hard work under the hood. It get's created using the tlbimp.exe tool. Visual Studio typically calls it for you whenever you are referencing a library from the COM tab. The result is the library you wanted to register: InterOp.Libary.dll. This library redefines all types of the type library of the COM server, implements the rules required by COM and performs the actual calls for you. However it is a managed .NET library which does not define the methods, described earlier. This is why regsvr32 cannot find the DllRegisterServer entry point.

The way described above is only a one-way with an unmanaged COM server and a managed .NET client. There is also the other way, with the counterparts tlbexp.exe and regasm.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top