Accessing a remote COM object via C#
I have an exe file written using unmanaged C++ which contains a COM object. In order to access it from a managed C# application, I generated an interop assembly. I was able to use this with great success when both apps were running on the same PC.
Now, I have a requirement to make my C# app access the COM object on a remote PC and the existing code gave me some problems. I had to make some small changes e.g.
Type ReportItemSetup = Type.GetTypeFromProgID("ACME.REPORTITEMSETUP.1", remotePCName);
RpiSetup = (IReportItemSetup)Activator.CreateInstance(ReportItemSetup);
became
Guid gris = new Guid("{147FF3D1-8A00-11F0-9A6C-0000C099D00B}");
Type ReportItemSetup = Type.GetTypeFromCLSID(gris, remotePCName, true);
RpiSetup = (IReportItemSetup)Activator.CreateInstance(ReportItemSetup);
This enabled me to get a bit further through the code but then I reached another problem.
I use :
REPORTITEMSETUPClass rpis = new REPORTITEMSETUPClass();
where REPORTITEMSETUPClass is (edited for brevity)
namespace Acme.ReportItemServers.Interop
{
[ClassInterface(ClassInterfaceType.None)]
[TypeLibType(TypeLibTypeFlags.FAppObject | TypeLibTypeFlags.FCanCreate | TypeLibTypeFlags.FPreDeclId)]
[ComConversionLoss]
[Guid("147FF3D1-8A00-11F0-9A6C-0000C099D00B")]
public class REPORTITEMSETUPClass : IReportItemSetup, REPORTITEMSETUP, INotifySrc
{
public REPORTITEMSETUPClass();
... 开发者_Python百科snip ...
public virtual void INotifySrc_AddUser(INotify pNotify, string bstrUserName);
... snip ...
}
}
I need to make a call to AddUser on the INotifySrc interface but the new call gives me the error :
Retrieving the COM class factory for component with CLSID {147FF3D1-8A00-11F0-9A6C-0000C099D00B} failed due to the following error:
80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
This error is perfectly correct since it is not registered on the local machine.
My question is therefore : is it not possible to use the registration on the remote PC? The Activator.CreateInstance had no problems with the class not being registered locally.
I think you must write a serviced component to do this. This involves some COM+ magic and can be quite complex. Look here for a summary: http://msdn.microsoft.com/en-us/library/3x7357ez%28v=vs.71%29.aspx
Create a subclass of System.EnterpriseServices.ServicedComponent and then install it in COM+ on the server, then export a COM+ proxy (msi) from the server, and install this proxy on the client.
精彩评论