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.
Related
I am trying to use Registration-free WinRT by adding an application manifest following https://blogs.windows.com/windowsdeveloper/2019/04/30/enhancing-non-packaged-desktop-apps-using-windows-runtime-components/ to my DLL which is used as a in-proc COM server.
However, I get REGDB_E_CLASSNOTREG when the runtime class is instantiated. I used mt.exe to make sure the manifest is embedded. I am on Win-10 2004. Is this supposed to be working for win32 in-proc DLL servers? Is there an API call to register the component manually?
It appears that the Dll activation context is not used as active activation context by the loader as found in https://stackoverflow.com/a/48308884 .
Instead we have to save the context and activate it before instantiating our runtime class as shown below:
In DllMain:
if (dwReason == DLL_PROCESS_ATTACH)
{
GetCurrentActCtx(&hActCtx);
}
And before instantiating the Runtime class:
ActivateActCtx(hActCtx, &cookie);
Class1 c;
DeactivateActCtx(0, cookie);
auto x = c.MyProperty();
By manually using the activation context API along with the embedded manifest in DLL, i can use winrt components without registration.
Make sure all dependencies related to WinRT component are present. Dependencies can be other required DLLs or VS runtime DLLs etc.
One problem I faced was: VCRUNTIME140_APP.dll not found, so I copied VC runtime libraries from the following location:
C:\program files
(x86)\msbuild\15.0.net.netnative\15.0.24211\x64\ilc\lib\MSCRT
to the output folder, post this FFmpegInteropX component got loaded into application (I think this can be solved by installing Microsoft.VCRTForwarders.140 nuget, but haven't tried it yet)
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.
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.
I have a C# library that I am using for a COM object in unmanaged C++ code. I registered the library using Visual Studio's checkbox "Register For Com Interop" and set ComVisible to true.
imported the tlb to the C++ app..... when I run it, I get a "Class Not Registered"....
This has worked before, but this started happening after I moved the directory of my C# project to a different location.... yes I did re-register the library after I moved it.
I've removed all references from the registry... I 've even tried doing a gacutil.exe /i on it... no dice.
Anyone know how to fix this?
A better way of using unmanaged objects in managed code is to use C++ / CLI. You can easily create a managed wrapper around the native object.
If you don't have explicit CLSID set on your managed object, it's possible that the move and rebuild has generated a new CLSID. Make sure your unmanaged project does not have a stale copy of the typelib.
Go to HKCR\CLSID\{XXXX} and ensure that the class registration for the managed object points to the right managed dll.
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.