unable to create TLB from the Com dll - interop

I have WMI class in a COM dll. I was trying to create a RCW for it in C#.NET. I used tlbexp.exe to get the type library from the COM dll but it throws an error stating "unable to load one of the dependencies".
I understood that it is trying to load one of the DLL it is referring internally, how can i come to know which dll it is trying to load and can i successfully complete the process if i some how get the dll from internet?

Use "Dependency Walker" on your DLL.

Related

Having an issue importing a tlb file into my MFC Application

I'm trying to create a MFC Automation COM object using MFC Library DLL but I am having issues. I have created the DLL and the TLB file has been generated. When I want to import the TLB file into a MFC Application, Visual Studios tells me
Cannot open source file C:/Users/XXX/documents/visual studio 2015/projects/ComDlgInDll/TestApp/ComDlgInDll.tlh
This is the command I type:
#import "..\Debug\ComDlgInDll.tlb" no_namespace
And even if I just type
#import
It will just go right ahead to the path and say that it cannot find the TLH file.
I don't have a TLH file at all, so I am confused as to why I cannot import it.
I would appreciate a solution since I am new to MFC and COM.
I also wanted to mention when I create a C# Windows Forms application, I add the DLL as a COM reference and then I type:
ComDlgInDll.ComDialogFactory var = new ComDlgInDll.ComDialogFactory();
var.GetDialog();
I get this error:
Retrieving the COM class factory for component with CLSID {1B2F7173-E140-47F3-8921-860BD434B05E} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
I even went into the registry to search for that uuid and I couldn't find it, which is odd. I am not sure why that uuid that is associated with a coclass is not being registered.
I would appreciate any help on it as I have been dealing with this for quite some time.

Out-of-process COM server without a proxy/stub DLL?

I am learning how to implement an out-of-process COM server and came across this Code Project article, Building a LOCAL COM Server and Client: A Step by Step Example.
I can build it, and it runs fine, but where is the proxy/stub DLL? All I can see is the IDL file from which the proxy/stub code is generated during the build. But how is the DLL built, and where is it?
The short answer is that all the interfaces are marked "oleautomation", so oleaut32.dll performs the marshaling, since COM knows how to marshal all the types used in the interfaces.
If "oleautomation" were missing, or a type was specified that COM doesn't know how to marshal by default (see the list here), your nondefault marshaler and its stub would be required.
You need Proxy/Stub project to help COM marshal your interfaces. When you create ATL C++ project with Visual Studio you typically have a secondary project with PS suffix created automatically, and this is your Proxy/Stub DLL. However, you might be doing fine without it at all (I personally never ever had to build and use it, even though I did have to deal with things like custom marshaling). If you provide type library with your project, it is registered and certain conditions are met - COM will supply automatic proxy/stub pair for you.
Bonus reading:
COM Proxy/Stub DLL and why do you need it
When Proxy/Stub Pair is Necessary

Problems referencing com dlls in vs 2010

I'm running a 32 bit ver of win7 in a vm. I am trying to reference 5 com dlls (VB6) in my .net project. These dlls (and their dependencies) are registered ok since I can use them natively as they form a part of another app and that app is working fine.
I try to set a reference to any of them directly in vs and I get the error message - Library not registered (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED)).
However, if I set a reference to another com component (which I don't want to reference but which in turn does reference these libs) I find that the references to these com dlls (which I do want to reference) gets set correctly in vs. I then just need to remove the ref to the unwanted dll and everything seems to be good to go.
If I look at the GUID and version details of one of the successfully referenced component, they appear to be the same as the GUID and version that appears in the caption of the error form, when I unsuccessfully try and set a reference to the same component directly.
BTW I have tried repairing the VS installation to no avail
I was wondering if someone could explain what I am doing wrong.
EDIT: Follow-up following Hans suggestion
So I ran
tlbimp mylib.dll
and it returned a TI1006 error - Output would overwrite the input file. So following suggestions found, I then issued
tlbimp mylib.dll /OUT:interop.mylib.dll
and this then returned the error
TlbImp : warning TI3011 : Type library importer has encountered an interface not derived from IUnknown: '_HiddenInterface'. The interface is skipped.
TlbImp : error TI1033 : Cannot find type 'ADODB._Recordset_Deprecated' in 'ADODB, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. There could be a mismatch between the referenced assembly and the type library.
But I'm not sure if this is a red herring since this lib could be referenced when successfully referencing the different higher level dll. I have tried with a dll which doesn't reference ADODB and that seems to work using tlbimp. So, e.g.
tlbimp myNONADODBlib.dll /OUT:interop.myNONADODBlib.dll
works from the commandline. However
tlbimp myNONADODBlib.dll
still generates the error TI1006 - output file will overwrite input file, and I cannot reference this into my .net project
EDIT:
There seems to be a problem with ADO and Win7 SP1. http://support.microsoft.com/kb/2517589 which would account for the deprecated error message (TI1033) I was getting, but not why VS was failing to create a CCW for the dll I can manually create a CCW via tlbimp.
EDIT (12/03/28 10:40):
So I have rebuilt the com dll with the suggested tlb. I can now successfully run
tlbimp mylib.dll
without getting any error messages and it appears to complete successfully. However, when I try and add a reference to that dll in VS, I still get the same original error message ( Library not registered (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED))). I have checked the registry and the registration looks ok i.e. it is pointing to the correct path - I'm wondering if it is a permissions-type issue - but I am running vs as admin.
EDIT (12/03/28 10:15):
So I ended up creating a new completely new vm with the same environment - and it worked ok. So I've no idea what is going on other than some registry corruption perhaps!
Many thx
Simon.
You need to use REGTLIB.exe to register the type library of the DLLs.
Type library registration is separate from component registration - the type library supports the introspection/type explorer functionality, and isn't usually required for running a precompiled application, though it may be required for compilation.

createObject in VB6 does fails when running exe

I have a VB6 program which tries to run a DLL written in C#.
This DLL has a COM interface so I can create an object of a class in it with "CreateObject".
The problem is that it runs and works well when I run it from the VB6 IDE, but when I make an EXE and try to run it, it throws the exception:
"Automation error. The system cannot find the file specified (-2147024894)."
Why is it happening and how can i solve it?
Look at Project, References in the IDE and look which dll or ocx file belongs to the object you are referencing with CreateObject (the Object Manager might also help to find out).
This dll file must be available when the exe is compiled, too. Usually, you need to have it registered with regsvr32.exe.
A technique I use to figure issues of this type is to open the add reference dialog in Visual Basic 6. I scroll the list of available COM Libraries and see if the problem DLL is listed. If it is then CreateObject should work, you should be able to assign it do a variant variant and use late binding to access it's members.
In addition try temporally set a reference to the variable and instead of using CreateObject use the = New and see what error messages, if any, it gives you. Generally I found them to be more informative then the ones thrown by CreateObject.
Finally it would help if you post the reason why you are choosing to use CreateObject instead of setting of a reference. If the DLL is a known object that will be continually used by the program then a reference should be set and early binding generally used.
Finally it may be that the error is resulting from a dependency of the C# COM DLL not the DLL itself. If for example I was to take a Com Library and properly register it but it relies on the COM Library Widget2000 and it NOT registered then it will throw the automation error. Especially if you are testing the EXE in it's installed environment and not the environment in which you complied it.
For example suppose I have a CAD program written in VB6 and I have source tree that begins with MyCAD. THe exe is in MyCAD/MainEXE and the shape library is in MyCAD/ShapeLibrary. I run the IDE everything is fine. Then I make my setup and goto my test machine and install it and it error on the creation of shapelibrary.
The first thing I would do it check if MainEXE will run straight out of the MainEXE directory of my source tree. That test will eliminate whether it is a install issue or a quirk of the IDE vs complied version. Then I would look at the setup and see what not being registered. Also look at either the source for the C# library or the setup for the library and see what dependencies it needs. Since it a complied COM DLL you should be able to use a dependency walker tool to see what COM references it needs. Finally make sure the correct version of the .NET framework is installed.
If you are compiling the C# DLL on your test machine - make sure you have ticked the register for COM Interop setting. If you are not compiling on the same machine you need to run RegAsm with the /codebase option.
try compiling it as an installer and include the dll/com that you use in the compilation of the installer package so that the dll/com that you use will be include in the compilation of your exe.., and install it in the windows not just copy past it.

Failed to generate factory object - 80040154 error

I inherited maintainance of a complex managed/unmanaged project and I hope I can ask this question in a concise way.....
I have an unmanaged class (C++) that I am trying to access through managed code (C#). This is achieved in the following way:
The unmanaged class (Prop) is compiled into an unmanaged dll (PropUnmanaged.dll)
PropUnmanaged.dll is registered with regsvr32
regsvr32 /s PropDLL
The classes and types in PropDLL are exposed to managed code using tlbimp
This creates a managed DLL (PropTypesManaged.dll)
This dll is not registered with regasm nor gacutil
The managed class (MClass) trying to access Prop is implemented in a project that has PropTypesManaged.dll as one of its dependencies
The project that implements MClass fails with the error message
Retrieving the COM class factory for component with CLSID {1EAD9D36-495C-44B2-8559-A6570E1ECE34} failed due to the following error: 80040154
The GUID 1EAD... refers to the GUID of the exposed managed type of the Prop class generated by tlbimp. It is in the registry
Web searches on the error code vaguely suggests that something has gone wrong with the regsvr32 step, but my system reports this step succeeded OK
Where do I start debugging this?
If you're running 64-bit Windows, make sure to change the Platform Target of your C# project to x86:
Open project properties, select the Build tab, under the "General" section, select "x86" from the Platform target drop-down.

Resources