簡體   English   中英

如何在點網中使用免注冊COM dll

[英]How to use Registration free COM dll in dot net

在我的一個項目中,我有一個使用C ++ DLL的c#應用程序。 目前在客戶端PC上,我們在注冊表中的COM組件上注冊C ++ DLLS,以便我們在C#中使用它們。

我在NET上了解到有一個免費解決方案可以從微軟獲得鏈接http://msdn.microsoft.com/en-us/library/ms973913.aspx

但閱讀后我沒有太多線索,因為我的應用程序架構如下所示

  1. 我有2個C ++ dll LET SAY CPForms.dll和Rules.dll。
  2. Rule.dll包含在CPForms.dll中
  3. 我有1個C#dll讓我說使用CPForms.DLL的ConsumeForm.dll
  4. 我有另一個使用ConsumeForm.dll的C#Exe

我的客戶端只打開C#Exe,后者又調用ConsumeForm.dll,它進一步調用CPForms.dll,顯示C ++表單(UI),有按鈕驗證,當用戶在內部使用C ++ Rules.dll單擊該按鈕時。 目前我在注冊表中注冊了兩個C ++ dll。

現在客戶端只希望將Rule.dll作為RegFree安裝引用,因為Rule.dll經常更改,並且客戶端不想使用管理員帳戶一次又一次地注銷和注冊。

其他那個客戶端可以注冊CPForms.dll。

我的問題是我們如何生成清單文件? 它在我的場景中將如何運作?

注意:請考慮在此處使用清單,以獲得更好的解決方案:

怎么做沒有清單

在COM注冊表是這是可選的一個進程內服務器的服務

再次: 您不必注冊對象以創建它。 如果它沒有注冊(並且不在清單中),則無法使用CoCreateInstance創建它,因為注冊表(或清單)告訴CoCreateInstance要加載哪個DLL。

但是,您可以使用LoadLibraryGetProcAddressDllGetClassObjectIClassFactory::CreateInstance創建它。

(注意,您不會獲得任何COM +服務,並且您不能以這種方式創建進程外對象,或者其線程模型與創建線程不兼容的對象。如果您不要求COM為您執行此操作這些事情成了你的問題)。

CoCreateInstance提供的服務是為LoadLibrary調用找到正確的DLL,並為您調用其他函數。 (並且檢查線程模型是兼容的,在適當的線程上創建,並使用CoMarshalInterthreadInterfaceInStream / CoUnmarshalInterfaceAndReleaseStream來編組接口,如果它們不是。這聽起來像很多工作但是如果你只有一個STA therad你幾乎可以忽略所有問題。)

像這樣的東西應該做的伎倆:

// Really you should break this up int GetClassFactoryFromDLL, then reuse the class factory.
// But this is all from memory...
// Load CLSID_MyID, from DLL pszMyDllPath
typedef HRESULT __stdcall (*_PFNDLLGETCLASSOBJECT)(
  __in   REFCLSID rclsid,
  __in   REFIID riid,
  __out  LPVOID *ppv
) PFNDLLGETCLASSOBJECT;

HRESULT CreateInstanceFromDll(LPCTSTR pszMyDllPath, CLSID clsidMyClass, IUknown** ppunkRet)
{
    // Handle bad callers
    *ppunkRet = NULL;
    HANDLE hDLL = LoadLibrary(pszMyDllPath);
    if(hDLL == NULL)
    {
        // Failed to load
        return HRESULT_FROM_NTSTATUS(GetLastError());
    }
    PFNDLLGETCLASSOBJECT pfnDllGetClassObject = GetProcAddress(hDLL);
    if(pfnDllGetClassObject == NULL)
    {
        // Not a COM dll
        HRESULT hrRet = HRESULT_FROM_NTSTATUS(GetLastError());
        FreeLibrary(hDLL);hDLL = NULL;
        return hrRet;
    }
    IClassFactory* pClassFactory = NULL;
    HRESULT hr = pfnDllGetClassObject(clsidMyClass, IID_IClassFactory, &pClassFactory);
    if(FAILED(hr)){
        FreeLibrary(hDLL);hDLL = NULL;
        return hr;
    }
    hr = pClassFactory->CreateInstance(NULL, IID_IUnknown, &ppunkRet);
    pClassFactory->Release();
    if(FAILED(hr))
    {
        *ppunkRet = NULL;
        FreeLibrary(hDLL);
        return hr;
    }
    return hr;
}

注意:這將允許您創建對象。 但是,如果您調用的對象本身依賴於已注冊,則它將無法正常運行。

特別是,許多IDispatch實現依賴於類型庫。 如果是特定對象的情況,則GetIDsOfNamesGetTypeInfo將失敗,並且您將無法對該對象使用后期綁定方法。 這包括在C#中使用dynamic ,以及在Python中使用dynamic語言。

其他方法,如雙接口方法和不從IDispatch繼承的接口可能會工作,但即使IDispatch方法不這樣做。

底線:為了使免注冊COM工作,被實例化的對象不得依賴於自己的注冊。

對於那些為了Registration free COM dll in dot net中搜索Registration free COM dll in dot net而跳轉到這個問題的人,我能夠在這個答案https://stackoverflow.com/a/19996424/173073中以C#的Reg Free方式使用AutoItX COM對象。 創建和使用其他Reg Free對象將類似。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM