C# Com Interop class 方法在 VB6 中不可见?

C# Com Interop class methods are not visible in VB6?

我已经在 .NET 中创建了一个 C# Com Interop class 并且我已经在我的开发机器上适当地注册了它并且 在程序集中将 Com-Visible 设置为 true.但是,当我在我的 vb6 应用程序中引用该库时,我能够看到库名称、class 名称但 none 方法或与其关联的属性?

如果有人能帮我解决这个问题,我已经卡了好久了!

这是我的class:

using System;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace VNDBUtils
{
public enum VNConstants : long
{
    cenMySQLDataStore = 32
}

[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("CF4EFB82-6EE1-4A84-9CA9-07B135888B68")]
[ComVisible(true)]
public interface IVNSqlFormatter
{
    //Properties
    long DS_Type { get; set; }
    string DS_Query { get; set; }

    //Methods
    string Format_Entity(string strString);
    string MqStrMan_MakeStringEndWith(string strString, string strMatch);
    bool MqStrMan_StringEndsWith(string strString, string strMatch);
    string MqStrMan_MakeStringStartWith(string strString, string StrMatch);
    bool MqStrMan_StringStartsWith(string strString, string strMatch);
    string Right(string value, int length);
    string Left(string value, int maxLength);
    string Format_Value(string strString);
}



[ClassInterface(ClassInterfaceType.None)]
[Guid("3884D59D-AB76-41E7-82B6-21C66DBDCBF3")]
[ComVisible(true)]
public class VNSqlFormatter : IVNSqlFormatter
{

    private const string SQUARE_LEFT = "[";
    private const string SQUARE_RIGHT = "]";

    public long DS_Type { get; set; }
    public string DS_Query { get; set; }

    public string Format_Entity(string strString)
    {           
        strString = strString.Trim();

        if (DS_Type == (long)VNConstants.cenMySQLDataStore)
        {
            return strString;
        }
        else
        {
            return MqStrMan_MakeStringEndWith(MqStrMan_MakeStringStartWith(strString, SQUARE_LEFT), SQUARE_RIGHT);
        }

    }

    public string MqStrMan_MakeStringEndWith(string strString, string strMatch)
    {
        if (MqStrMan_StringEndsWith(strString, strMatch) == false)
        {
            return strString + strMatch;
        }
        else
        {
            return strString; 
        }

    }

    public bool MqStrMan_StringEndsWith(string strString, string strMatch)
    {
        return String.Equals(Right(strString, strMatch.Length), strMatch);

    }

    public string MqStrMan_MakeStringStartWith(string strString, string strMatch)
    {
        if (MqStrMan_StringStartsWith(strString, strMatch) == false)
        {
            return strMatch + strString;
        }
        else
        {
            return strString; 
        }
    }

    public bool MqStrMan_StringStartsWith(string strString, string strMatch)
    {
       return String.Equals(Left(strString, strMatch.Length), strMatch);
    }

    public string Right(string value, int length)
    {
        if (String.IsNullOrEmpty(value))
        {
            return String.Empty;
        }

        return value.Length <= length ? value : value.Substring(value.Length - length);
    }

    public string Left(string value, int maxLength)
    {
        if(String.IsNullOrEmpty(value))
        {
            return String.Empty; 
        }

        maxLength = Math.Abs(maxLength);
        return value.Length <= maxLength ? value : value.Substring(0, maxLength);
    }

    public string Format_Value(string strString)
    {
            return strString.Replace("'", "''");
    }

}

}

您是否编辑了 AssemblyInfo.cs 文件?

通常,这是默认值:

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("e2e2a417-bd3d-414d-97f9-91196ce1c63a")]

您需要将 [assembly: ComVisible(false)] 设置为 true

评论中的讨论导致如下,未设置ProgId属性。

[ClassInterface(ClassInterfaceType.None)]
[Guid("3884D59D-AB76-41E7-82B6-21C66DBDCBF3")]
[ComVisible(true)]
[ProgId("VNDBUtils.VNSqlFormatter")]
public class VNSqlFormatter : IVNSqlFormatter
{
    /* implementation information */
}

觉得这太长了,无法作为评论添加到

ProgID 应自动生成。而且它似乎应该已经生成为您手动添加的相同字符串。

根据微软文档 Assembly to Type Library Conversion Summary - Exported Type Conversion:

The export process also automatically generates a programmatic identifier (ProgId) by combining the namespace and type name. For example, the ProgId generated for the managed LinkedList class shown in the previous examples is A.B.LinkedList.

Combining the namespace and type name can result in an invalid ProgId. A ProgId is limited to 39 characters and can contain no punctuation characters other than periods. To avoid these limitations, you can specify a ProgId in your source code by applying the ProgIdAttribute, rather than allowing the export process to generate an identifier for you.

如果您只是为了测试而取出 ProgID 属性,那么您可以检查编译时创建的类型库(使用 OleView 等工具)并查看它生成的 ProgID。它可能会生成一个对 VB6 无效的 ProgID,尽管从您的示例中的代码来看情况似乎并非如此。