An application I have recently started work on has to register two dll's, "because of ActiveX".
This makes it difficult to have multiple version of the application present on your machine - say the installed product version, and Debug and Release versions of the latest development sources.
What are the alternatives to registration for ActiveX.
If your application loads the ActiveX objects, there are a couple of options. The first option if you are using XP or newer, it to use a Registration-Free COM with a Manifest file as explained on MSDN. The idea is to declare your COM (ActiveX) components in a manifest file instead of the registry. So for MyApp.exe, create MyApp.exe.manifest with the following (using your DLL file name and CLSID):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="MyApp_ActiveX" version="1.0.0.1"
processorArchitecture="x86" publicKeyToken="0000000000000000" />
<file name="MyActiveX.dll">
<comClass clsid="{0000000-0000-0000-0000-000000000000}" threadingModel="Both" />
</file>
</assembly>
The other option as DougN mentioned is to roll your own CoCreateInstance() to create the object. The following C++ (plus ATL) code should do it (going from memory so double check the code):
typedef int (__stdcall *LPDLLGETCLASSOBJECT)(REFCLSID, REFIID, void**);
// LoadInterface() - Load COM Interface from DLL without using registry.
//
// USAGE:
// HMODULE hModule = 0;
// CComPtr<IMyActiveX> pActiveX;
// if(SUCCEEDED(LoadInterface("C:\\Debug\\MyActiveX.dll", CLSID_MyActiveX, IID_IMyActiveX, (void**)&pActiveX, &hModule)))
// {
// // TODO: use pActiveX
//
// // caller must call FreeLibrary(hModule) when done
// pActiveX = 0;
// FreeLibrary(hModule);
// }
//
HRESULT LoadInterface(LPCTSTR pDllPath, REFCLSID rClsid, REFIID riid, LPVOID* ppv, HMODULE *pModule)
{
if(pModule == 0 || ppv == 0) return E_POINTER;
HMODULE hModule = LoadLibrary(pDllPath);
if(hModule == 0) return E_FAIL;
HREUSLT hr = E_POINTER;
CComPtr<IClassFactory> classFactory;
LPDLLGETCLASSOBJECT pGetClassObject = (LPDLLGETCLASSOBJECT)GetProcAddress(hModule, "DllGetClassObject");
if(pGetClassObject)
{
hr = pGetClassObject(rClsid, IID_IClassFactory, (void**)&classFactory);
if(SUCCEEDED(hr))
{
hr = classFactory->CreateInstance(0, riid, (void**)ppv);
if(SUCCEEDED(hr))
{
*pModule = hModule;
return S_OK;
}
}
}
// unload library on error
if(hModule)
{
FreeLibrary(hModule);
}
return hr;
}