如何修复编译错误'System.ServiceModel.ComIntegration.IParseDisplayName'由于其保护级别而无法访问

时间:2017-03-29 16:08:49

标签: c# wcf com com-interop moniker

我正在尝试在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}")  

1 个答案:

答案 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);
}