我有一个现有的COM Exe Server,以及调用它的VBA或.NET代码。我们希望无需安装或修改注册表即可使其工作,以便其计算机上不是管理员的其他用户可以使用它。
我们假设无法更改/修改COM Exe Server(昂贵)。
问题1: 根据我在Registering a Running EXE Server中所做的事情,EXE服务器可以调用CoRegisterClassObject在类表中注册CLSID。这是否意味着客户端应该能够从那里获得CoGetClassObject? (甚至没有该类型/类的注册表项?)
问题2: 如果以上是正确的,我的EXE服务器使用CComModule(不建议使用,是),我可以看到确实在调用CoRegisterClassObject。有没有办法验证类表,看看是否正确完成了?
问题3:
这是我正在使用的片段。 clsid和iid指的是相应的clsid和iid guids。在调用CreateInstance时,接口未注册(来自HRESULT:0x80040155的异常)失败。这让我很伤心,对于可能出错的任何想法?
var factory = UnsafeNativeMethods.CoGetClassObject(
clsid,
RegistrationClassContext.LocalServer,
IntPtr.Zero,
typeof(UnsafeNativeMethods.IClassFactory).GUID)
as UnsafeNativeMethods.IClassFactory;
factory.CreateInstance(null, ref iid, out obj);
答案 0 :(得分:6)
问题1:从我在注册正在运行的EXE服务器中所做的工作, EXE服务器可以调用CoRegisterClassObject来注册CLSID 班级表。这是否意味着客户应该能够 那里的CoGetClassObject? (甚至没有注册表项 类型/类别?)
是。 CoRegisterClassObject
就足够了(没有注册表),可以让任何使用CoCreateInstance
调用CLSCTX_LOCAL_SERVER
的客户端使用您的流程外对象。但是,您可能遇到编组调用问题,因为未注册COM代理/存根DLL和/或类型库。因此,诸如IDispatch
,IOleCommandTarget
之类的众所周知的接口将被编组而没有问题,但任何自定义接口都将失败。
但是,还有其他方法可以让客户端使用EXE服务器。仅举几例:RegisterActiveObject
,IRunningObjectTable
。
问题2:如果上述内容正确,我的EXE服务器使用CComModule (不赞成,是)我可以看到确实在呼唤 CoRegisterClassObject。有没有办法验证类表,所以看看 这是正确的吗?
我只能考虑调用CoGetClassObject
或CoCreateInstance
(需要CLSCTX_LOCAL_SERVER
标志)来验证。
问题3:这是我正在使用的代码段。 clsid和iid指的是 相应的clsid和iid guids。它失败了接口没有 在调用中注册(来自HRESULT的异常:0x80040155) 的CreateInstance。这让我很伤心,对于可能出错的任何想法?
这很奇怪。如果COM标准编组程序无法找到接口的代理/存根工厂,则COM标准编组程序返回0x80040155(REGDB_E_IIDNOTREG),但IClassFactory
不需要自定义代理。您确定在GUID
的C#定义中有正确的IClassFactory
吗?那应该是Guid("00000001-0000-0000-C000-000000000046")
。