2009-05-01 2 views
2

최근에 작업을 시작한 응용 프로그램은 "ActiveX 때문에"두 dll을 등록해야합니다.ActiveX에 대한 dll 등록의 대안

이렇게하면 설치된 제품 버전 및 최신 개발 소스의 디버그 및 릴리스 버전과 같이 여러 버전의 응용 프로그램을 컴퓨터에 설치하는 것이 어려워집니다.

ActiveX의 등록 방법에는 어떤 것이 있습니까?

답변

3

응용 프로그램에서 ActiveX 개체를로드하는 경우 몇 가지 옵션이 있습니다. 첫 번째 옵션은 XP 이상을 사용하는 경우 MSDN에 설명 된 것처럼 Manifest 파일과 함께 Registration-Free COM을 사용하는 것입니다. COM (ActiveX) 구성 요소를 레지스트리 대신 매니페스트 파일에 선언하는 것이 아이디어입니다. 그래서 MyApp.exe의 위해와 MyApp.exe.manifest을 만드는 (당신의 DLL 파일 이름과 CLSID 사용) 다음

DougN 같은 다른 옵션은 언급
<?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> 

자신의를 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

트릭은 끔찍한 생각입니다. 해당 시스템에 설치된 다른 버전의 응용 프로그램을 등록 취소 할 수 있습니다. – Francis

0

ProgID을 사용하여 ActiveX 컨트롤 버전을 지정할 수 있습니다.

0

가 나는 박쥐 솔루션이 반드시 끔찍한 생각하지 않습니다. 대부분의 간단한 ActiveX 컨트롤은 자체 등록/등록 해제입니다. 하지만 동시에 한 번에 디버그 버전이나 릴리스 버전을 실행하도록 제한합니다.

큰 문제 ("DLL 지옥"의 본질)이며 .NET 및 Java의 인기가 큰 이유 중 하나입니다.

.NET은 Windows 2000 및 Windows 98 SE에서 도입 된 기능인 side-by-side sharing을 사용한다고 생각합니다. 나는 당신이 .NET을 사용할 필요가 없다고 생각한다. (당신은 COM Interop을하고 있다고 말하지 않았다.)

MSDN의 http://msdn.microsoft.com/en-us/library/ms811700.aspx, "로컬 응용 프로그램에서 공유 구성 요소 구현"에서 .local 파일을 만드는 것이 좋습니다. 나는 그것이 어떻게 작동하는지 완전히 명확하지는 않지만 그것이 올바른 접근이라고 생각합니다.