繁体   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