c# – COM Interop,客户端未在进程外COM中查找接口
我使用Microsoft的
CSExeCOMServer作为设置进程外COM服务器的基础,但它无法正常工作.服务器是64位,客户端是32位.
这是示例界面 [Guid(XXCryptService.InterfaceId),ComVisible(true)/*,InterfaceType(ComInterfaceType.InterfaceIsIUnknown)*/] public interface IXXCryptService { [DispId(1)] string Encrypt(string password,string key); [DispId(2)] string Decrypt(string password,string key); } 和班级 [ClassInterface(ClassInterfaceType.None)] [Guid(XXCryptService.ClassId),ComVisible(true)] public class XXCryptService : ReferenceCountedObject,IXXCryptService { internal const string ClassId = "C5F6938B-5593-4872-B8C7-B47EE33EABCD"; internal const string InterfaceId = "6990FF5F-22E2-4032-8B98-36115DBCEFFF"; [EditorBrowsable(EditorBrowsableState.Never)] [ComRegisterFunction()] public static void Register(Type t) { try { COMHelper.RegasmRegisterLocalServer(t); } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } } [EditorBrowsable(EditorBrowsableState.Never)] [ComUnregisterFunction()] public static void Unregister(Type t) { try { COMHelper.RegasmUnregisterLocalServer(t); } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } } public string Encrypt(string password,string key) { return "Encrypted"; } public string Decrypt(string password,string key) { return "Decrypted"; } } 该程序运行,但是当客户端连接它时,在服务器触发ObjectClassFactory上的CreateInstance后,它在客户端崩溃,并使用Marshal.GetComInterfaceForObject(new XXCryptService(),typeof(IXXCryptService))返回ppvObject上的对象并返回0. 在.NET上运行客户端会触发“无法将类型为’COMTest.XXCryptService’的COM对象’转换为接口类型’COMTest.IXXCryptService’.此操作失败,因为QueryInterface调用COM组件上的IID为{6990FF5F-的接口22E2-4032-8B98-36115DBCEFFF}由于以下错误而失败:找不到元素.(HRESULT异常:0x8002802B(TYPE_E_ELEMENTNOTFOUND)).“. [Guid("6990FF5F-22E2-4032-8B98-36115DBCEFFF")] //[InterfaceType(ComInterfaceType.InterfaceIsDual)] interface IXXCryptService { [DispId(1)] string Encrypt(string password,string key); } [ComImport,Guid("C5F6938B-5593-4872-B8C7-B47EE33EABCD")] class XXCryptService { } class Program { static void Main(string[] args) { XXCryptService cs = new XXCryptService(); IXXCryptService ics = (IXXCryptService) cs; Console.WriteLine(ics.Encrypt("Test","Test")); Console.ReadKey(); } } 在Delphi上运行客户端会在EIntfCastError中触发异常,并显示消息“Interface not supported”.使用“导入类型库”导入COM并像这样使用. procedure TForm1.FormCreate(Sender: TObject); begin FCrypter := CoXXCryptService.Create; end; TLB界面看起来像这样 IXXCryptService = interface(IDispatch) ['{6990FF5F-22E2-4032-8B98-36115DBCEFFF}'] function Encrypt(const password: WideString; const key: WideString): WideString; safecall; function Decrypt(const password: WideString; const key: WideString): WideString; safecall; end; // *********************************************************************// // DispIntf: IXXCryptServiceDisp // Flags: (4416) Dual OleAutomation Dispatchable // GUID: {6990FF5F-22E2-4032-8B98-36115DBCEFFF} // *********************************************************************// IXXCryptServiceDisp = dispinterface ['{6990FF5F-22E2-4032-8B98-36115DBCEFFF}'] function Encrypt(const password: WideString; const key: WideString): WideString; dispid 1; function Decrypt(const password: WideString; const key: WideString): WideString; dispid 2; end; 我已通过注册表检查,一切似乎都已正确注册,所以我不明白为什么我应该得到这个问题. 这里有人对可能出现的问题有任何疑问吗? 编辑:在64位编译客户端,这是正常的.此外,它引用了错误的路径,在我调整它后,我在.NET x86客户端上遇到了不同的错误 此操作失败,因为由于以下错误,对IID为“{6990FF5F-22E2-4032-8B98-36115DBCEFFF}”的接口的COM组件的QueryInterface调用失败:加载类型库/ DLL时出错. (来自HRESULT的异常:0x80029C4A(TYPE_E_CANTLOADLIBRARY)) 解决方法
这是注册的问题,而且只有当程序集与regasm具有相同的目标时,才会执行regasm. regasm应该有一个“/ com_oop或something”参数,使其注册LocalServer32而不是InprocServer32,并在64位系统上为32位和64位注册.
为了解决这个问题,我不得不暂时将可执行文件(使用相同的路径)编译为32位,运行32位regasm(使用/ tlb:..),然后编译回64位,运行64位regasm(使用/ tlb:..再次),现在它适用于32位和64位对64位可执行文件. CSExeComServer有一个注册和取消注册方法,它手动删除InprocServer32密钥并添加LocalServer32.为了确保这个工作正常,我将改变这个,检测它是否在64位系统上注册,然后让它在那里正确注册.当我完成后,我会将我做的更改发布到注册方法中. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |