Как создать COM видимый класс в C#?

Я использовал Visual Studio 2010 (.NET 4). Мне нужно создать COM- объект (в C#) и не знаю, с чего начать (какой тип проекта использовать и т. Д.)

3 ответа

Решение

Хорошо, я нашел решение, и я напишу это здесь для общего блага.

  1. Запустите VS2010 от имени администратора.
  2. Откройте проект библиотеки классов (например, MyProject).
  3. Добавьте новый интерфейс в проект (см. Пример ниже).
  4. Добавить using System.Runtime.InteropServices; в файл
  5. Добавьте атрибуты InterfaceType, Guid к интерфейсу.
  6. Вы можете сгенерировать Guid используя Tools->Generate GUID (опция 4).
  7. Добавьте класс, который реализует интерфейс.
  8. Добавьте атрибуты ClassInterface, Guid, ProgId в интерфейс.
    Соглашение ProgId: {namespace}.{Class}
  9. В папке "Свойства" проекта в файле AssemblyInfo установите для ComVisible значение true.
  10. В меню свойств проекта на вкладке сборки отметьте "Зарегистрироваться для взаимодействия COM"
  11. Постройте проект

Теперь вы можете использовать свой COM-объект, используя его ProgID.

пример: код 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.");

        }

    }
}

и VB скрипт с использованием COM:

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

и результат будет:

Запускаю скрипты для заработка

Шаги создания

  1. Запустите Visual Studio 2013 от имени администратора
  2. Установить расширение Visual Studio Проекты установщика Microsoft Visual Studio
  3. Создать проект библиотеки классов (WinFormActivex)
  4. Создайте пример окна формы (MainWindow)
  5. Создать новый интерфейс компонента (ILauncher)
  6. Создать новый интерфейс безопасности (IObjectSafety)
  7. Создайте элемент управления компонента (Launcher), который реализует интерфейсы и запустите окно.
  8. Убедитесь, что все GUID сгенерированы вами
  9. Убедитесь, что проект помечен для COM
  10. Создайте проект установки (LauncherInstaller) с первичным выходом WinFormActivex со свойством Register = vsdrpCOM
  11. Установить LauncherInstaller
  12. Запустите тестовую страницу в проводнике (test.html)

MainWindow Вы можете создать обычную форму, здесь предварительно сгенерировано.

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

Launcher Пожалуйста, сгенерируйте свой 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 (Launcher) совпадает.

<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>

Рекомендации

Вы можете использовать проект библиотеки классов. Объявите тип с методами, которые будут представлены как объект COM.

Убедитесь, что сборка сделана видимой для COM:

альтернативный текст

И, наконец, зарегистрируйте его, используя regasm.exe:

regasm.exe /codebase mylib.dll

Теперь сборка представляется как объект COM, и объявленный вами тип может использоваться любым клиентом, поддерживающим COM.

Другие вопросы по тегам