我正在尝试在C#中实现一个COM组件,它将使用GetObject调用并提供自定义字符串。两个组件已经使用GetObject("winmgmts:\.\root\cimv2")
和LDAP GetObject("LDAP://example.com/OU=Users,DC=asp,DC=rippe,DC=com")
执行此WMI。我被这种自定义激活语法所吸引,并想复制它。
我似乎必须实现Class Com接口IParseDisplayName。
所以我在C#中尝试这样做,我有简单的COM对象,可以进行简单的计算。我被困在尝试实现IParseDisplayName,我得到以下错误
`'System.ServiceModel.ComIntegration.IParseDisplayName' is inaccessible due to its protection level`
现在我已经看到了其他带有这些错误的C#问题,它们是通过升级公共访问来解决的访问修饰符问题。但我不控制这个界面,因为它是一个系统界面。
我该如何解决?这是目前的代码。
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");
}
}
}
编辑:另外,我认为Windows Communication Foundation(WCF)也在这里使用相同的机制是link,这里是一个代码片段。如果是真的那么这证明它可以在C#中完成!
Set typedServiceMoniker = GetObject(
"service4:address=http://localhost/ServiceModelSamples/service.svc, binding=wsHttpBinding,
contractType={9213C6D2-5A6F-3D26-839B-3BA9B82228D3}")
答案 0 :(得分:1)
您应该能够自己重新声明该界面。关于.NET中COM接口的有趣之处在于,您可以在多个位置定义它们并且它们不会发生冲突。只需将其粘贴在您的代码中,并使用此定义而不是System.ServiceModel.ComIntegration
中的定义。
[ComImport]
[SuppressUnmanagedCodeSecurity]
[Guid("0000011a-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IParseDisplayName
{
void ParseDisplayName(IBindCtx pbc, [MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName, IntPtr pchEaten, IntPtr ppmkOut);
}