I'm using Microsoft's CSExeCOMServer as a base for setting up a Out-of-process COM server, but it's not working properly. The server is 64 bit, and the client is 32 bit.
Here's the sample interface
[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);
}
And the class
[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";
}
}
The program runs, but when a client connects it crashes on the client after the server has triggered CreateInstance on the ObjectClassFactory, and returned the object on ppvObject with Marshal.GetComInterfaceForObject(new XXCryptService(), typeof(IXXCryptService)) and returned 0.
Running the client on .NET triggers a "Unable to cast COM object of type 'COMTest.XXCryptService' to interface type 'COMTest.IXXCryptService'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{6990FF5F-22E2-4032-8B98-36115DBCEFFF}' failed due to the following error: Element not found. (Exception from 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();
}
}
Running the client on Delphi triggers an exception in EIntfCastError with message 'Interface not supported'. COM is imported with "Import Type Library" and used like this.
procedure TForm1.FormCreate(Sender: TObject);
begin
FCrypter := CoXXCryptService.Create;
end;
TLB interface looks like this
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;
I have checked through the registry, and everything seems to be registered properly, so I don't understand why I should get this problem.
Anyone here have any clue on what might be the problem?
Edit: Compiled the client in 64bit and that's working properly. Also, it referenced the wrong path, after I adjusted it I got a different error on the .NET x86 client
This operation failed because the QueryInterface call on the COM component for the interface with IID '{6990FF5F-22E2-4032-8B98-36115DBCEFFF}' failed due to the following error: Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY))
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
? We usually define dual interfaces for accessing COM from Delphi. 2) Are your running on a 64 bit Windows? In this case, you'll have to compile and register all COM objects as x86, and run regasm from the 32 bit windows virtual folder. – Arnaud Bouchez