2009-05-01 80 views
2

我最近开始工作的应用程序必须注册两个DLL,“因为ActiveX”。有什么替代DLL注册的ActiveX

这使得在您的计算机上存在多个版本的应用程序变得困难 - 比如说已安装的产品版本以及最新开发资源的调试和发布版本。

什么是ActiveX注册的替代方法。

回答

3

如果您的应用程序加载ActiveX对象,有几个选项。第一种选择,如果您使用XP或更新的版本,则使用上解释的带有Manifest文件的免注册COM。这个想法是在清单文件中声明你的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; 
} 
0

没有我能想到的。这就是COM(因此ActiveX)背后的全部基本原理。

0

如果您控制加载ActiveX控件的代码,而其他人不需要加载它,则可以跳过注册并手动处理您自己的CreateInstance调用:LoadLibrary,获取指向Factory对象的指针并直接创建实例。

大约10年前在一个项目上做到了这一点,它的工作很棒。但是,如果你不能这样做(也许你不控制调用CreateInstance的代码),那么只需创建两个批处理文件并将它们放在桌面上:一个用于注册Debug,一个用于注册Release DLL文件。来回切换变得相当容易。

+0

.bat技巧是一个可怕的想法 - 您可以注销在该系统上安装的其他版本的应用程序。 – Francis 2009-05-01 14:23:16

0

您可以使用ProgID版本控制ActiveX控件。

0

我不认为蝙蝠的解决方案必然是可怕的。大多数简单的ActiveX控件都是自注册/取消注册的。但它仍然限制您一次运行调试版本或发行版本,而不是同时运行。

这是一个很大的问题(这是“DLL地狱”的本质),也是.NET和Java流行的重要原因。

我相信.NET利用并行共享,这是Windows 2000和Windows 98 SE引入的一项功能。我不认为你需要.NET来使用它(你没有说你在做COM互操作)。

在MSDN上有一篇比较冗长的文章http://msdn.microsoft.com/en-us/library/ms811700.aspx“在应用程序中实现并行组件共享”,建议创建一个.local文件。我不完全清楚这是如何工作的,但我认为这是正确的方法。