Как создать COM видимый класс в С#?
Я использовал Visual Studio 2010 (.NET 4). Мне нужно создать COM- объект (в С#) и не знаю, с чего начать (какой тип проекта использовать и т.д.)
Ответы
Ответ 1
OK Я нашел решение, и я напишу его здесь для общего блага.
- Запустите VS2010 в качестве администратора.
- Откройте проект библиотеки классов (exmaple - MyProject).
- Добавить новый интерфейс в проект (см. пример ниже).
- Добавить
using System.Runtime.InteropServices;
в файл
- Добавьте атрибуты InterfaceType, Guid в интерфейс.
- Вы можете создать Guid с помощью Tools- > Generate GUID (вариант 4).
- Добавить класс, реализующий интерфейс.
- Добавьте атрибуты ClassInterface, Guid, ProgId в интерфейс.
Соглашение ProgId - {namespace}. {Class}
- В папке "Свойства" в проекте в файле AssemblyInfo установите "ComVisible" в значение "true".
- В меню свойств проекта в закладке сборки отметьте "Регистрация для COM-взаимодействия",
- Создайте проект
теперь вы можете использовать свой COM-объект, используя его ProgID.
Пример:
код С#:
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 script с помощью COM:
set obj = createObject("PSLauncher.PSLauncher")
obj.launch()
и вывод будет:
Я запускаю сценарии для жизни
Ответ 2
Шаги создания
- Запустите Visual Studio 2013 с правами администратора
- Установить расширение Visual Studio Проекты установщика Microsoft Visual Studio
- Создайте проект библиотеки классов (WinFormActivex)
- Создайте свой пример формы окна (MainWindow)
- Создайте новый интерфейс компонента (ILauncher)
- Создайте новый интерфейс безопасности (IObjectSafety)
- Создайте компонентный элемент управления (Launcher), который реализует интерфейсы и запускает окно.
- Убедитесь, что все GUID созданы вами.
- Убедитесь, что проект отмечен для COM
- Создайте проект установки (LauncherInstaller) с основным выходом WinFormActivex со свойством
Register = vsdrpCOM
- Установить LauncherInstaller
- Запустите тестовую страницу в explorer (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 (Launcher) 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>
Ссылки
Ответ 3
Вы можете использовать проект библиотеки классов. Объявите тип с методами, которые будут отображаться как COM-объект.
Убедитесь, что сборка сделана COM-видимой:
И, наконец, зарегистрируйте его, используя regasm.exe:
regasm.exe /codebase mylib.dll
Теперь сборка отображается как COM-объект, и объявленный вами тип может быть использован любым клиентом, поддерживающим COM.