简体   繁体   English

如何在点网中使用免注册COM dll

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

In one of my Project, I have c# application which is using C++ DLL. 在我的一个项目中,我有一个使用C ++ DLL的c#应用程序。 Currently at client PC we are registering C++ DLLS at COM components in the registry so that we will use them in C#. 目前在客户端PC上,我们在注册表中的COM组件上注册C ++ DLLS,以便我们在C#中使用它们。

I learn on NET that there is a Reg Free solution available from microsoft at link http://msdn.microsoft.com/en-us/library/ms973913.aspx 我在NET上了解到有一个免费解决方案可以从微软获得链接http://msdn.microsoft.com/en-us/library/ms973913.aspx

But after reading I didn't get much clue because my application architecture is different as following 但阅读后我没有太多线索,因为我的应用程序架构如下所示

  1. I am having 2 C++ dlls LET SAY CPForms.dll and Rules.dll. 我有2个C ++ dll LET SAY CPForms.dll和Rules.dll。
  2. Rule.dll is include inside CPForms.dll Rule.dll包含在CPForms.dll中
  3. I have 1 C# dll let say ConsumeForm.dll which is using CPForms.DLL 我有1个C#dll让我说使用CPForms.DLL的ConsumeForm.dll
  4. I have another C# Exe which is using ConsumeForm.dll 我有另一个使用ConsumeForm.dll的C#Exe

My client is only opening C# Exe which in turn is calling ConsumeForm.dll which is further calling CPForms.dll which shows C++ form (UI), there is button validate, when user click that button it internally using C++ Rules.dll. 我的客户端只打开C#Exe,后者又调用ConsumeForm.dll,它进一步调用CPForms.dll,显示C ++表单(UI),有按钮验证,当用户在内部使用C ++ Rules.dll单击该按钮时。 Currently I am registering both C++ dlls in registry. 目前我在注册表中注册了两个C ++ dll。

Now client only want Rule.dll to be referenced as RegFree installation, because Rule.dll changes frequently and the client don't want to unregister and register again and again using Admin account. 现在客户端只希望将Rule.dll作为RegFree安装引用,因为Rule.dll经常更改,并且客户端不想使用管理员帐户一次又一次地注销和注册。

Other then that client is OK with registration of CPForms.dll. 其他那个客户端可以注册CPForms.dll。

My question is how we can generate manifest file? 我的问题是我们如何生成清单文件? And how it will work in my scenario? 它在我的场景中将如何运作?

Note: Consider using a manifest as in the answer here for a better solution: 注意:请考虑在此处使用清单,以获得更好的解决方案:

How to do it without a manifest 怎么做没有清单

The COM registry is a service which is optional for an inproc server. 在COM注册表是这是可选的一个进程内服务器的服务

Again: You do not have to register an object in order to create it. 再次: 您不必注册对象以创建它。 If it is not registered, (and not in a manifest) you cannot create it with CoCreateInstance , because the registry (or manifest) is what tells CoCreateInstance which DLL to load. 如果它没有注册(并且不在清单中),则无法使用CoCreateInstance创建它,因为注册表(或清单)告诉CoCreateInstance要加载哪个DLL。

However you can create it with LoadLibrary , GetProcAddress , DllGetClassObject and IClassFactory::CreateInstance . 但是,您可以使用LoadLibraryGetProcAddressDllGetClassObjectIClassFactory::CreateInstance创建它。

(Note you will not get any COM+ services, and you cannot create out-of-process objects in this way, or objects whose threading model isn't compatible with the creating thread. If you don't ask COM to do it for you these things become your problem). (注意,您不会获得任何COM +服务,并且您不能以这种方式创建进程外对象,或者其线程模型与创建线程不兼容的对象。如果您不要求COM为您执行此操作这些事情成了你的问题)。

The service which CoCreateInstance provides is to locate the correct DLL for the call to LoadLibrary, and just call the other functions for you. CoCreateInstance提供的服务是为LoadLibrary调用找到正确的DLL,并为您调用其他函数。 (And checking the threading models are compatible, creating on the appropriate thread, and using CoMarshalInterthreadInterfaceInStream/CoUnmarshalInterfaceAndReleaseStream to marshal the interface if they are not. That sounds like a lot of work but if you just have one STA therad you can pretty much ignore all the issues.) (并且检查线程模型是兼容的,在适当的线程上创建,并使用CoMarshalInterthreadInterfaceInStream / CoUnmarshalInterfaceAndReleaseStream来编组接口,如果它们不是。这听起来像很多工作但是如果你只有一个STA therad你几乎可以忽略所有问题。)

Something like this should do the trick: 像这样的东西应该做的伎俩:

// 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;
}

Note: This will allow you to create the object. 注意:这将允许您创建对象。 However if the object you call is itself reliant onbeing registered, it will not function correctly. 但是,如果您调用的对象本身依赖于已注册,则它将无法正常运行。

In particular, many IDispatch implementations rely on the type library. 特别是,许多IDispatch实现依赖于类型库。 If that's the case for a particular object, then GetIDsOfNames and GetTypeInfo will fail, and you will not be able to use late-bound methods with the object. 如果是特定对象的情况,则GetIDsOfNamesGetTypeInfo将失败,并且您将无法对该对象使用后期绑定方法。 This includes using dynamic in C#, and dynamic languages such as Python. 这包括在C#中使用dynamic ,以及在Python中使用dynamic语言。

Other methods such as dual interface methods and interfaces not inheriting from IDispatch may well work however even if the IDispatch methods do not. 其他方法,如双接口方法和不从IDispatch继承的接口可能会工作,但即使IDispatch方法不这样做。

Bottom line: For registration-free COM to work, the object being instantiated must not rely on its own registration. 底线:为了使免注册COM工作,被实例化的对象不得依赖于自己的注册。

For those who will jump to this question in search for Registration free COM dll in dot net , I was able to use AutoItX COM object in Reg Free manner from C# in this answer https://stackoverflow.com/a/19996424/173073 . 对于那些为了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对象。 Creating and using other Reg Free objects would be similar. 创建和使用其他Reg Free对象将类似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM