我使用 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”。此操作失败,因为对具有 IID 的接口的 COM 组件调用 QueryInterface '{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);
[DispId(2)] string Decrypt(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 中触发异常,并显示消息“不支持接口”。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))