In one of my Project, I have c# application which is using C++ DLL. Currently at client PC we are registering C++ DLLS at COM components in the registry so that we will use them in C#.
I learn on NET that there is a Reg Free solution available from microsoft at link http://msdn.microsoft.com/en-us/library/ms973913.aspx
But after reading I didn't get much clue because my application architecture is different as following
My client is only opening C# Exe which in turn is calling ConsumeForm.dll which is further calling CPForms.dll which shows C++ form (UI), there is button validate, when user click that button it internally using C++ Rules.dll. Currently I am registering both C++ dlls in registry.
Now client only want Rule.dll to be referenced as RegFree installation, because Rule.dll changes frequently and the client don't want to unregister and register again and again using Admin account.
Other then that client is OK with registration of CPForms.dll.
My question is how we can generate manifest file? And how it will work in my scenario?
Registration-free COM interop activates a component without using the Windows registry to store assembly information. Instead of registering a component on a computer during deployment, you create Win32-style manifest files at design time that contain information about binding and activation.
Note: Consider using a manifest as in the answer here for a better solution:
How to do it without a manifest
The COM registry is a service which is optional for an inproc server.
Again: You do not have to register an object in order to create it. If it is not registered, (and not in a manifest) you cannot create it with CoCreateInstance
, because the registry (or manifest) is what tells CoCreateInstance
which DLL to load.
However you can create it with LoadLibrary
, GetProcAddress
, DllGetClassObject
and IClassFactory::CreateInstance
.
(Note you will not get any COM+ services, and you cannot create out-of-process objects in this way, or objects whose threading model isn't compatible with the creating thread. If you don't ask COM to do it for you these things become your problem).
The service which CoCreateInstance
provides is to locate the correct DLL for the call to LoadLibrary, and just call the other functions for you. (And checking the threading models are compatible, creating on the appropriate thread, and using CoMarshalInterthreadInterfaceInStream/CoUnmarshalInterfaceAndReleaseStream to marshal the interface if they are not. That sounds like a lot of work but if you just have one STA therad you can pretty much ignore all the issues.)
Something like this should do the trick:
// Really you should break this up int GetClassFactoryFromDLL, then reuse the class factory.
// But this is all from memory...
// Load CLSID_MyID, from DLL pszMyDllPath
typedef HRESULT __stdcall (*_PFNDLLGETCLASSOBJECT)(
__in REFCLSID rclsid,
__in REFIID riid,
__out LPVOID *ppv
) PFNDLLGETCLASSOBJECT;
HRESULT CreateInstanceFromDll(LPCTSTR pszMyDllPath, CLSID clsidMyClass, IUknown** ppunkRet)
{
// Handle bad callers
*ppunkRet = NULL;
HANDLE hDLL = LoadLibrary(pszMyDllPath);
if(hDLL == NULL)
{
// Failed to load
return HRESULT_FROM_NTSTATUS(GetLastError());
}
PFNDLLGETCLASSOBJECT pfnDllGetClassObject = GetProcAddress(hDLL);
if(pfnDllGetClassObject == NULL)
{
// Not a COM dll
HRESULT hrRet = HRESULT_FROM_NTSTATUS(GetLastError());
FreeLibrary(hDLL);hDLL = NULL;
return hrRet;
}
IClassFactory* pClassFactory = NULL;
HRESULT hr = pfnDllGetClassObject(clsidMyClass, IID_IClassFactory, &pClassFactory);
if(FAILED(hr)){
FreeLibrary(hDLL);hDLL = NULL;
return hr;
}
hr = pClassFactory->CreateInstance(NULL, IID_IUnknown, &ppunkRet);
pClassFactory->Release();
if(FAILED(hr))
{
*ppunkRet = NULL;
FreeLibrary(hDLL);
return hr;
}
return hr;
}
Note: This will allow you to create the object. However if the object you call is itself reliant onbeing registered, it will not function correctly.
In particular, many IDispatch
implementations rely on the type library. If that's the case for a particular object, then GetIDsOfNames
and GetTypeInfo
will fail, and you will not be able to use late-bound methods with the object. This includes using dynamic
in C#, and dynamic languages such as Python.
Other methods such as dual interface methods and interfaces not inheriting from IDispatch may well work however even if the IDispatch methods do not.
Bottom line: For registration-free COM to work, the object being instantiated must not rely on its own registration.
For those who will jump to this question in search for Registration free COM dll in dot net
, I was able to use AutoItX COM object in Reg Free manner from C# in this answer https://stackoverflow.com/a/19996424/173073. Creating and using other Reg Free objects would be similar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With