如何修复编译错误 'System.ServiceModel.ComIntegration.IParseDisplayName' is unaccessible due to its protection level'
How to fix compile error 'System.ServiceModel.ComIntegration.IParseDisplayName' is inaccessible due to its protection level'
我正在尝试在 C# 中实现一个 COM 组件,该组件可以使用 GetObject 调用并提供自定义字符串。两个组件已经使用 GetObject("winmgmts:\.\root\cimv2")
执行此 WMI 并使用 GetObject("LDAP://example.com/OU=Users,DC=asp,DC=rippe,DC=com")
执行 LDAP。我被这种自定义激活语法所吸引,想复制它。
看来我必须实现 Class Com 接口 IParseDisplayName。
所以我尝试在 C# 中执行此操作,我有一个简单的 COM 对象,可以执行简单的计算。我在尝试实施 IParseDisplayName 时遇到困难,出现以下错误
`'System.ServiceModel.ComIntegration.IParseDisplayName' is inaccessible due to its protection level`
现在我已经看到其他 C# 问题出现这些错误,它们是访问修饰符问题,可以通过升级到 public 来解决。但是我不控制这个界面,因为它是系统界面。
请问如何解决?这是目前的代码。
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}")
您应该能够自己重新声明该接口。 .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);
}
我正在尝试在 C# 中实现一个 COM 组件,该组件可以使用 GetObject 调用并提供自定义字符串。两个组件已经使用 GetObject("winmgmts:\.\root\cimv2")
执行此 WMI 并使用 GetObject("LDAP://example.com/OU=Users,DC=asp,DC=rippe,DC=com")
执行 LDAP。我被这种自定义激活语法所吸引,想复制它。
看来我必须实现 Class Com 接口 IParseDisplayName。
所以我尝试在 C# 中执行此操作,我有一个简单的 COM 对象,可以执行简单的计算。我在尝试实施 IParseDisplayName 时遇到困难,出现以下错误
`'System.ServiceModel.ComIntegration.IParseDisplayName' is inaccessible due to its protection level`
现在我已经看到其他 C# 问题出现这些错误,它们是访问修饰符问题,可以通过升级到 public 来解决。但是我不控制这个界面,因为它是系统界面。
请问如何解决?这是目前的代码。
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}")
您应该能够自己重新声明该接口。 .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);
}