私が最近作業を開始したアプリケーションは、「ActiveXのために」2つのdllを登録する必要があります。ActiveXのDLL登録の代替方法
これにより、インストールされている製品バージョン、最新の開発ソースのDebugおよびReleaseバージョンなど、複数のバージョンのアプリケーションをマシンにインストールすることが困難になります。
ActiveXの登録方法にはどのようなものがありますか?
私が最近作業を開始したアプリケーションは、「ActiveXのために」2つのdllを登録する必要があります。ActiveXのDLL登録の代替方法
これにより、インストールされている製品バージョン、最新の開発ソースのDebugおよびReleaseバージョンなど、複数のバージョンのアプリケーションをマシンにインストールすることが困難になります。
ActiveXの登録方法にはどのようなものがありますか?
アプリケーションでActiveXオブジェクトが読み込まれる場合、いくつかのオプションがあります。 XP以降を使用している場合の最初のオプションは、MSDNで説明したマニフェストファイルを持つRegistration-Free COMを使用することです。 COM(ActiveX)コンポーネントをレジストリではなくマニフェストファイルに宣言することです。だから、MYAPP.EXEのために(あなたのDLLファイルの名前とCLSIDを使用して)以下でMyApp.exe.manifestを作成します。
<?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。前後の切り替えは非常に簡単になります。
ActiveXコントロールのバージョンはProgIDです。
私は.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ファイルの作成を示唆しています。私はその仕組みについて完全にはっきりしていませんが、正しいアプローチだと思います。
バットトリックはひどい考えです。そのシステムにインストールされている他のバージョンのアプリケーションを登録解除することができます。 – Francis