Reputation: 670
My C# application will use third-party C# COM dll. I want to call all members of that dll in the most beautiful way - like after adding this dll to project references and "using" statement. But from other side I want to determine if dll is not presents in the system and show exception from my application(like i could using late-binding). So how can I catch dll missing , and using this dll that VisualStudio will see all types of this dll likes after using statement?
Com dll is registering using regasm.exe. This tool also produce .tlb file from dll. Maybe I can use this .tlb somehow?
Upvotes: 0
Views: 813
Reputation: 8448
I suppose best way to do it is to get COM object from progID and try to create it.
Type comType = Type.GetTypeFromProgID(progID);
if (comType == null)
throw new Exception("COM object not found!);
dynamic comObject = Activbator.CreateInstance(comType);
comObject.SomeOperation();
Added value of this solution is that one version of your application will work both with x86 and x64 COM object, so OS version doesn't matter.
Upvotes: 1
Reputation: 11596
Visual Studio generates an so called Interop-Library for you. This means if you are referencing to a library that is called MyCOMLib.dll
it will generate an assembly called MyComLib.Interop.dll
. This assembly contains .NET wrapper objects (so called Runtime Callable Wrappers) you are instancing from your .NET application. You can generate this interop-library on your own using the TlbImp.exe-Tool.
So what you are actually instancing are not actual COM-objects, but .NET objects that work as some kind of proxy for those COM-objects. Internally they are calling CoCreateInstance
or CoCreateInstanceEx
and the COM class factories for you. Also they manage the memory handling of those objects. (You can take influence on this management using Marshal.ReleaseComObject
, but you should notice that this can be dangerous).
This means your application does allways ship together with those interop assemblies. If those assemblies are not present (and you've referenced them using Project References) the application will not run (it will throw an exception on startup). If the assemblies can be loaded to you application's AppDomain there will be no problems until you are creating an interop-type object. The RCW calls CoCreateInstance
/CoCreateInstanceEx
together with the CLSID (that the interop assembly knows thanks to the TlbImp.exe-tool). If those class ID's are not found inside the registry your application will throw an runtime exception.
A good way to check if the library exists is to check for the unique library ID and version during application setup. Those are stored inside the registry. You need to know the GUID and version of the library, then you'll find them under HKLM\Software\Classes\TypeLib\{Guid}\{Version}
.
The best way is to deliver your application together with the 3rd party redistributable package that installs the library on it's own. This also ensures that other applications do not remove the 3rd party type-libraries. That's the way Microsoft does it with the Visual C++ libraries or DirectX.
Upvotes: 1