ActiveXのdll登録に代わるものは何ですか
-
03-07-2019 - |
質問
最近作業を開始したアプリケーションは、「ActiveXが原因で」という2つのdllを登録する必要があります。
これにより、マシンにアプリケーションの複数のバージョン(インストールされている製品バージョン、最新の開発ソースのデバッグバージョンとリリースバージョンなど)が存在しにくくなります。
ActiveXの登録の代替手段は何ですか。
解決
アプリケーションがActiveXオブジェクトをロードする場合、いくつかのオプションがあります。 XP以降を使用している場合の最初のオプションは、 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;
}
他のヒント
考えられることはありません。これがCOM(つまりActiveX)の背後にある全体の理論的根拠です。
ActiveXコントロールをロードするコードを制御し、他に誰もロードする必要がない場合は、登録をスキップして、独自のCreateInstance呼び出しを手動で処理できます:LoadLibrary、Factoryオブジェクトへのポインターを取得し、インスタンスを直接作成します。
約10年前のプロジェクトでそれを行いましたが、うまくいきました。
ただし、それができない場合(CreateInstanceを呼び出すコードを制御しない場合があります)、2つのバッチファイルを作成してデスクトップに配置します。1つはデバッグを登録し、もう1つはリリースDLLを登録します。前後に切り替えると非常に簡単になります。
ProgID 。
.batソリューションが必ずしも恐ろしいとは思わない。最も単純なActiveXコントロールは、自己登録/登録解除です。ただし、同時にデバッグバージョンまたはリリースバージョンのいずれかを同時に実行することはできません。
これは大きな問題であり(「DLL地獄」の本質です)、. NETとJavaの人気の理由の大部分です。
.NETは、Windows 2000およびWindows 98 SEで導入された機能であるサイドバイサイド共有を利用すると考えています。 .NETを使用するのに.NETは必要ないと思います(COM相互運用を行っているとは言わなかった)。
MSDNのやや長い記事が http://msdn.microsoftにあります。 .com / en-us / library / ms811700.aspx 、「アプリケーションでのサイドバイサイドコンポーネント共有の実装」、 .localファイルを作成することをお勧めします。私はそれがどのように機能するかについて完全に明確ではありませんが、私はそれが正しいアプローチだと思います。