-1

我正在尝试在 C# 中实现一个 COM 组件,该组件可以使用 GetObject 调用并提供自定义字符串。两个组件已经使用 .WMIGetObject("winmgmts:\.\root\cimv2")和 LDAP 使用GetObject("LDAP://example.com/OU=Users,DC=asp,DC=rippe,DC=com"). 我被这种自定义激活语法所吸引,并想复制它。

看来我必须实现 Class Com Interface 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) 也使用相同的机制,这里是一个链接,这里是一个代码片段。如果为真,那么这证明它可以在 C# 中完成!

Set typedServiceMoniker = GetObject(  
"service4:address=http://localhost/ServiceModelSamples/service.svc,      binding=wsHttpBinding,   
contractType={9213C6D2-5A6F-3D26-839B-3BA9B82228D3}")  
4

1 回答 1

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);
}
于 2017-03-29T19:15:00.697 回答