I'm trying to implement a COM component in C# that will be invokable using GetObject and supplying a custom string. Two components already do this WMI with GetObject("winmgmts:\.\root\cimv2")
and LDAP with GetObject("LDAP://example.com/OU=Users,DC=asp,DC=rippe,DC=com")
. I'm attracted to this custom activation syntax and would like to replicate it.
It seems I have to implement the Class Com Interface IParseDisplayName.
So I'm trying to do this in C#, I have simple COM object that does simple calculations. I am stuck trying to implement IParseDisplayName, I get the following error
`'System.ServiceModel.ComIntegration.IParseDisplayName' is inaccessible due to its protection level`
Now I've seen other C# questions with these errors and they are access modifier issues that are solved by upgrading access to public. But I do not control this interface as it is a system interface.
How do I solve please? Here the code as it currently stands.
using Microsoft.Win32;
using System;
using System.ServiceModel;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Xml;
namespace MonikerParseDisplayName
{
// In Project Properties->Build->Check 'Interop for COM'
// In AssemblyInfo.cs [assembly: ComVisible(true)]
// compile with /unsafe In Project Properties->Build->Check 'Allow unsafe code'
public interface ICalculator
{
double add( double a, double b);
double mult(double a, double b);
}
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(ICalculator))]
//[System.Security.SuppressUnmanagedCodeSecurity]
public class Calculator : ICalculator, System.ServiceModel.ComIntegration.IParseDisplayName //, System.Runtime.InteropServices.ComTypes.IMoniker
{
public double add( double a, double b)
{
return a+b;
}
public double mult(double a, double b)
{
return a*b;
}
//void IParseDisplayName.ParseDisplayName(IBindCtx pbc, IMoniker pmkToLeft,
// string pszDisplayName, out int pchEaten, out IMoniker ppmkOut)
void IParseDisplayName.ParseDisplayName(IBindCtx pbc, IMoniker pmkToLeft,
string pszDisplayName, IntPtr pchEaten, IntPtr ppmkOut)
{
return new Exception("Not yet implemented");
}
}
}
EDIT: Also, I think Windows Communication Foundation (WCF) also uses same mechanism here is a link and here a code snippet. If true then this proves that it can be done in C#!
Set typedServiceMoniker = GetObject(
"service4:address=http://localhost/ServiceModelSamples/service.svc, binding=wsHttpBinding,
contractType={9213C6D2-5A6F-3D26-839B-3BA9B82228D3}")