我最近开始工作的应用程序必须注册两个dll,“因为ActiveX”。
这使您的计算机上存在多个版本的应用程序变得很困难 - 例如已安装的产品版本以及最新开发源的调试版和发布版。
ActiveX注册的替代方法有哪些。
答案 0 :(得分:3)
如果您的应用程序加载ActiveX对象,则有几个选项。如果您使用的是XP或更新版本的第一个选项,它将使用带有清单文件的免注册COM,如MSDN中所述。我们的想法是在清单文件而不是注册表中声明您的COM(ActiveX)组件。因此,对于MyApp.exe,使用以下内容创建MyApp.exe.manifest(使用您的DLL文件名和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>
DougN提到的另一个选项是滚动你自己的CoCreateInstance()来创建对象。下面的C ++(加上ATL)代码应该这样做(从内存开始,所以仔细检查代码):
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;
}
答案 1 :(得分:0)
没有我能想到的。这就是COM背后的整个基本原理(因此也是ActiveX)。
答案 2 :(得分:0)
如果您控制加载ActiveX控件的代码,并且没有其他人需要加载它,您可以跳过注册并手动处理您自己的CreateInstance调用:LoadLibrary,获取指向Factory对象的指针,并直接创建实例。
大约10年前在一个项目中做到了这一点并且效果很好。
但是,如果你不能这样做(也许你不能控制调用CreateInstance的代码),那么只需创建两个批处理文件并将它们放在桌面上:一个用于注册Debug,另一个用于注册Release DLL 。来回切换变得非常容易。
答案 3 :(得分:0)
您可以使用ProgID。
对ActiveX控件进行版本控制答案 4 :(得分:0)
我不认为.bat解决方案一定很糟糕。大多数简单的ActiveX控件都是自注册/取消注册。但它仍然限制您一次运行调试版本或发布版本,而不是同时运行。
这是一个大问题(它是“DLL Hell”的精髓),也是.NET和Java流行的重要原因。
我相信.NET利用了并排共享,这是Windows 2000和Windows 98 SE引入的一项功能。我认为你不需要.NET来使用它(你没有说你在做COM Interop)。
MSDN上有一篇篇幅篇幅http://msdn.microsoft.com/en-us/library/ms811700.aspx,“在应用程序中实现并排组件共享”,建议创建一个.local文件。我不完全清楚它是如何工作的,但我认为这是正确的方法。