代码之家  ›  专栏  ›  技术社区  ›  Sancarn

有没有一种更干净的方法使COM可见的应用程序?

  •  1
  • Sancarn  · 技术社区  · 6 年前

    给定特定类别:

    public class Klass
    {
        public int value;
        public void doSomething(){
            return;
        }
    }
    

    据我所知,要使所说的类COM可见,需要做一些事情:

    1. 进口 System.Runtime.InteropServices
    2. 为类创建接口。
    3. 扩展创建的接口。
    4. 创建两个唯一的guid,一个用于接口,另一个用于类。
    5. 向接口添加调度ID。

    产生类似于:

    [Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
    public interface IKlass
    {
        [DispId(0)]
        public int value;
        [DispId(1)]
        public void doSomething();
    }
    
    [Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"),
        ClassInterface(ClassInterfaceType.None)]
    public class Klass : IKlass
    {
        public int value;
        public void doSomething(){
            return;
        }
    }
    

    在我看来,生成的代码看起来非常恶心。。。问题是,有没有一个简单的方法来创建这些COM接口?我可以想象自己修改构建过程来给出 interop 特色。例如。

    public interop class Klass
    {
        public interop int value;
        //...
    }
    

    然而,这是非标准的,这也有它的问题。Visual Studio/C中有什么内置的东西可以用来让构建COM接口更简单/更干净吗?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Sancarn    6 年前

    由建议 Zohar Peled 最好的方法是 RegAsm.exe :

    1. 创建一些C类库“TestProject”:

    using System.Windows.Forms;
    namespace TestProject
    {
        // Note. Only public classes are exported to COM!
        public class Test
        {
            // Note. Only public methods are exported to COM!
            public void testIt() {
                MessageBox.Show("Yellow world");
            }
        }
    }
    

    重要: 只有公共类导出到COM。并且只有这些类的公共方法可以通过COM对象实例使用。


    1. 签署项目。

    2. 在AssemblyInfo.cs集中 [assembly: ComVisible(false)] [assembly: ComVisible(true)] . 注意:您还可以在要公开给COM的每个类之前使用属性[ComVisible(true)”。这只是将默认值设置为 true 如果构建一个API

    3. 建立项目。

    4. 经营皇室。请记住使用Regasm的正确版本(32位/64位)和.NET框架的版本:


    # .NET v4.5 64-bit
    "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" -tlb -codebase "C:\Users\sancarn\Desktop\tbd\TestProject\TestProject\bin\Debug\TestProject.dll" -verbose
    
    # .NET v4.5 32-bit
    "C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" -tlb -codebase "C:\Users\sancarn\Desktop\tbd\TestProject\TestProject\bin\Debug\TestProject.dll" -verbose
    
    ...
    

    帝王应该输出如下内容:

    Microsoft .NET Framework Assembly Registration Utility version 4.7.3056.0
    for Microsoft .NET Framework version 4.7.3056.0
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    Types registered successfully
    Type 'TestProject.Test' exported.
    Assembly exported to 'C:\Users\sancarn\Desktop\tbd\TestProject\TestProject\bin\Debug\TestProject.tlb', and the type library was registered successfully
    

    现在可以在VBScript中测试文件,例如:

    Dim o As Object
    Set o = CreateObject("TestProject.Test")
    Call o.testIt
    
        2
  •  1
  •   D Stanley    6 年前

    Sancarn回答了您的问题,但请注意,这也使项目COM中所有与COM兼容的类都可见,这是您可能不希望看到的(请参见 here here ). 如果您没有显式设置uuid,那么当您使用早期绑定的客户机(如VB或VBA,而不是VBScript,后者是后期绑定的)访问类时,在部署时会遇到问题。

    是的,它不是“干净的”,但COM也不是, 尤其地 当您想向后期绑定客户端公开它时,可以使用实时VBScript。

    我还将把您的公共字段改为属性,这对公共成员来说更为标准:

        [Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
        public interface IKlass
        {
            [DispId(0)]
            public int value {get; set;}
            [DispId(1)]
            public void doSomething();
        }