如何在C#中创建COM可见类?

时间:2010-07-29 07:04:34

标签: visual-studio-2010 c#-4.0 com

我使用Visual Studio 2010(.NET 4)。我需要创建一个COM对象(在C#中)并且不知道如何开始(使用什么类型的项目等)。

3 个答案:

答案 0 :(得分:70)

好的,我找到了解决方案,我会在这里写一下,为了共同利益。

  1. 以管理员身份启动VS2010。
  2. 打开一个类库项目(exmaple - MyProject)。
  3. 向项目添加新界面(请参阅下面的示例)。
  4. 在文件中添加using System.Runtime.InteropServices;
  5. 将InterfaceType,Guid属性添加到接口。
  6. 您可以使用工具生成指南 - >生成GUID(选项4)。
  7. 添加实现该接口的类。
  8. 将属性ClassInterface,Guid,ProgId添加到界面中      ProgId约定是{namespace}。{class}
  9. 在AssemblyInfo文件中项目的Properties文件夹下,将ComVisible设置为true。
  10. 在项目属性菜单中,在构建选项卡标记“注册COM互操作”
  11. 构建项目

现在您可以使用它的ProgID来使用您的COM对象。

例如: C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Runtime.InteropServices;

namespace Launcher
{

    [InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
    public interface ILauncher
    {
        void launch();
    }

    [ClassInterface(ClassInterfaceType.None), Guid("YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYY"), ProgId("Launcher.Launcher")]
    public class Launcher : ILauncher
    {
        private string path = null;

        public void launch()
        {
            Console.WriteLine("I launch scripts for a living.");

        }

    }
}

和使用COM的VB脚本:

set obj = createObject("PSLauncher.PSLauncher") obj.launch()

,输出结果为:

我为生活启动脚本

答案 1 :(得分:16)

创建步骤

  1. 以管理员身份启动Visual Studio 2013
  2. 安装Visual Studio扩展程序Microsoft Visual Studio Installer Projects
  3. 创建一个类库项目(WinFormActivex)
  4. 创建示例窗口表单(MainWindow)
  5. 创建新的组件界面(ILauncher)
  6. 创建新的安全界面(IObjectSafety)
  7. 创建实现接口并启动窗口的组件控件(Launcher)。
  8. 检查所有GUID是否由您生成
  9. 检查项目是否标记为COM
  10. 使用WinFormActivex的主要输出创建安装项目(LauncherInstaller),其属性为Register = vsdrpCOM
  11. 安装LauncherInstaller
  12. 在资源管理器(test.html)中运行测试页
  13. <强>主窗口 您可以创建一个普通的表单,这里是预先生成的。

    public partial class MainWindow : Form
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
    
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
    
        #region Windows Form Designer generated code
    
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            //
            // textBox1
            //
            this.textBox1.Location = new System.Drawing.Point(42, 23);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 0;
            //
            // textBox2
            //
            this.textBox2.Location = new System.Drawing.Point(42, 65);
            this.textBox2.Name = "textBox2";
            this.textBox2.Size = new System.Drawing.Size(100, 20);
            this.textBox2.TabIndex = 0;
            //
            // MainWindow
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 261);
            this.Controls.Add(this.textBox2);
            this.Controls.Add(this.textBox1);
            this.Name = "MainWindow";
            this.Text = "MainWindow";
            this.ResumeLayout(false);
            this.PerformLayout();
    
        }
    
        #endregion
    
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.TextBox textBox2;
    }
    

    <强> ILauncher

    using System.Runtime.InteropServices;
    namespace WinFormActivex
    {
        [ComVisible(true)]
        [InterfaceType(ComInterfaceType.InterfaceIsDual)]
        [Guid("94D26775-05E0-4B9C-BC73-C06FE915CF89")]
        public interface ILauncher
        {
            void ShowWindow();
        }
    }
    

    <强> IObjectSafety的

    [ComImport()]
    [Guid("51105418-2E5C-4667-BFD6-50C71C5FD15C")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IObjectSafety
    {
        [PreserveSig()]
        int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions);
        [PreserveSig()]
        int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions);
        }
    

    <强>启动 请在此处生成您的GUID。

     [ComVisible(true)]
     [ClassInterface(ClassInterfaceType.None)]
     [Guid("D100C392-030A-411C-92B6-4DBE9AC7AA5A")]
     [ProgId("WinFormActivex.Launcher")]
     [ComDefaultInterface(typeof(ILauncher))]
     public class Launcher : UserControl, ILauncher, IObjectSafety
     {
         #region [ ILauncher ]
    
         public void ShowWindow()
         {
             var f = new MainWindow();
             f.StartPosition = FormStartPosition.Manual;
             f.Location = Screen.AllScreens[0].Bounds.Location;
             f.WindowState = FormWindowState.Normal;
             f.WindowState = FormWindowState.Maximized;
             f.ShowInTaskbar = false;
             f.Show();
         }
    
         #endregion
    
         #region [ IObjectSafety ]
    
         public enum ObjectSafetyOptions
         {
             INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001,
             INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002,
             INTERFACE_USES_DISPEX = 0x00000004,
             INTERFACE_USES_SECURITY_MANAGER = 0x00000008
         };
    
         public int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
         {
             ObjectSafetyOptions m_options = ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER | ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;
             pdwSupportedOptions = (int)m_options;
             pdwEnabledOptions = (int)m_options;
             return 0;
         }
    
         public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
         {
             return 0;
         }
    
         #endregion
     }
    

    <强>的test.html 请检查您的CLSID是否匹配(启动器)GUID。

    <html>
        <head>
            <objectname="activexLauncher" style='display:none' id='activexLauncher' classid='CLSID:D100C392-030A-411C-92B6-4DBE9AC7AA5A' codebase='WinFormActivex'></object>
          <script language="javascript">
            <!-- Load the ActiveX object  -->
            var x = new ActiveXObject("WinFormActivex.Launcher");
            alert(x.GetText());
          </script>
        </head>
        <body>
        </body>
    </html>
    

    <强>参考

答案 2 :(得分:13)

您可以使用类库项目。使用将作为COM对象公开的方法声明一个类型。

确保程序集已变为COM可见:

alt text

最后使用regasm.exe注册:

regasm.exe /codebase mylib.dll

现在程序集作为COM对象公开,任何支持COM的客户端都可以使用您声明的类型。