2

私が最近作業を開始したアプリケーションは、「ActiveXのため」に2つのdllを登録する必要があります。

これにより、複数のバージョンのアプリケーションをマシンに存在させることが困難になります。たとえば、インストールされている製品バージョンや、最新の開発ソースのデバッグバージョンとリリースバージョンなどです。

ActiveXの登録に代わるものは何ですか。

4

5 に答える 5

3

アプリケーションがActiveXオブジェクトをロードする場合、いくつかのオプションがあります。XP以降を使用している場合の最初のオプションは、MSDNで説明されているように、マニフェストファイルで登録不要の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;
 }
于 2009-05-02T04:00:23.507 に答える
0

ProgIDを使用してActiveXコントロールをバージョン管理できます。

于 2009-05-01T18:39:01.373 に答える
0

私が考えることができるものはありません。これがCOM(つまりActiveX)の背後にある全体的な論理的根拠です。

于 2009-05-01T14:11:00.690 に答える
0

ActiveXコントロールをロードするコードを制御し、他の誰もそれをロードする必要がない場合は、登録をスキップして、独自のCreateInstance呼び出しを手動で処理できます。LoadLibrary、Factoryオブジェクトへのポインターを取得し、インスタンスを直接作成します。

約10年前のプロジェクトでそれを行い、それはうまくいきました。

ただし、それができない場合(CreateInstanceを呼び出すコードを制御していない場合)は、2つのバッチファイルを作成してデスクトップに配置します。1つはデバッグを登録し、もう1つはリリースDLLを登録します。そうすれば、前後の切り替えが非常に簡単になります。

于 2009-05-01T14:15:55.827 に答える
0

.bat ソリューションが必ずしも恐ろしいとは思いません。ほとんどの単純な ActiveX コントロールは、自己登録/登録解除です。ただし、デバッグ バージョンまたはリリース バージョンのいずれかを同時に実行することはできず、両方を同時に実行することはできません。

これは大きな問題 (「DLL Hell」の本質) であり、.NET と Java の人気の大きな理由です。

.NET は、Windows 2000 と Windows 98 SE で導入された機能であるサイド バイ サイド共有を利用していると思います。.NET を使用する必要はないと思います (COM 相互運用を行っているとは言いませんでした)。

MSDN のhttp://msdn.microsoft.com/en-us/library/ms811700.aspxには、「Implementing Side-by-Side Component Sharing in Applications」というやや長い記事があり、.local ファイルの作成を提案しています。それがどのように機能するかは完全にはわかりませんが、それが正しいアプローチだと思います。

于 2009-05-06T01:27:47.003 に答える