Hem*_*yal 5 c# c++ com activex regfreecom
在我的一个项目中,我有一个使用C++ DLL的c#应用程序.目前在客户端PC上,我们在注册表中的COM组件上注册C++ DLLS,以便我们在C#中使用它们.
我在NET上了解到有一个免费解决方案可以从微软获得链接http://msdn.microsoft.com/en-us/library/ms973913.aspx
但阅读后我没有太多线索,因为我的应用程序架构如下所示
我的客户端只打开C#Exe,后者又调用ConsumeForm.dll,它进一步调用CPForms.dll,显示C++表单(UI),有按钮验证,当用户在内部使用C++ Rules.dll单击该按钮时.目前我在注册表中注册了两个C++ dll.
现在客户端只希望将Rule.dll作为RegFree安装引用,因为Rule.dll经常更改,并且客户端不想使用管理员帐户一次又一次地注销和注册.
其他那个客户端可以注册CPForms.dll.
我的问题是我们如何生成清单文件?它在我的场景中将如何运作?
注意:请考虑在此处使用清单,以获得更好的解决方案:
怎么做没有清单
在COM注册表是一个服务是可选的一个进程内的服务器.
再次:您不必注册对象以创建它. 如果它没有注册,(而不是在清单中)则无法创建它CoCreateInstance,因为注册表(或清单)是告诉CoCreateInstance加载哪个DLL的.
但是你可以创建LoadLibrary,GetProcAddress,DllGetClassObject和IClassFactory::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;
}
Run Code Online (Sandbox Code Playgroud)
注意:这将允许您创建对象.但是,如果您调用的对象本身依赖于已注册,则它将无法正常运行.
特别是,许多IDispatch实现依赖于类型库.如果是特定对象的情况GetIDsOfNames,GetTypeInfo则会失败,并且您将无法对该对象使用后期绑定方法.这包括dynamic在C#中使用,以及使用Python等动态语言.
其他方法,如双接口方法和不从IDispatch继承的接口可能会工作,但即使IDispatch方法不这样做.
底线:为了使免注册COM工作,被实例化的对象不得依赖于自己的注册.