web-dev-qa-db-ja.com

C#でCOM可視クラスを作成するにはどうすればよいですか?

Visual Studio 201 (.NET 4)を使用しています。 [〜#〜] com [〜#〜] オブジェクト(C#で)を作成する必要があり、開始方法(使用するプロジェクトの種類など)がわからない

48
Eyal

OK解決策を見つけたので、ここで一般的な利益のために書きます。

  1. VS2010を管理者として起動します。
  2. クラスライブラリプロジェクトを開きます(例-MyProject)。
  3. プロジェクトに新しいインターフェイスを追加します(以下の例を参照)。
  4. _using System.Runtime.InteropServices;_をファイルに追加します
  5. インターフェースに属性InterfaceType、Guidを追加します。
  6. [ツール]-> [生成] GUID(オプション4))を使用してGUIDを生成できます。
  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.");

        }

    }
}
_

およびVB COMを使用したスクリプト:

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

出力は次のようになります。

私は生活のためのスクリプトを起動します

70
Eyal

作成手順

  1. Visual Studio 2013を管理者として起動します
  2. Visual Studio拡張機能のインストール Microsoft Visual Studio Installer Projects
  3. クラスライブラリプロジェクト(WinFormActivex)を作成する
  4. サンプルウィンドウフォーム(MainWindow)を作成する
  5. 新しいコンポーネントインターフェイスを作成します(ILauncher)
  6. 新しいセキュリティインターフェイス(IObjectSafety)を作成する
  7. インターフェイスを実装し、ウィンドウを起動するコンポーネントコントロール(ランチャー)を作成します。
  8. すべてのGUIDが自分で生成されていることを確認してください
  9. プロジェクトがCOM用にマークされていることを確認します
  10. プロパティRegister = vsdrpCOMを持つWinFormActivexのプライマリ出力でセットアッププロジェクト(LauncherInstaller)を作成します
  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);
    }

LauncherGUIDここで生成してください。

 [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.htmlCLSIDが(ランチャー)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>

参考文献

16
Giulio Caccin

クラスライブラリプロジェクトを使用できます。 COMオブジェクトとして公開されるメソッドを持つ型を宣言します。

アセンブリがCOMに表示されていることを確認します。

alt text

そして最後に regasm.exe を使用して登録します:

regasm.exe /codebase mylib.dll

これで、アセンブリはCOMオブジェクトとして公開され、宣言した型はCOMをサポートするクライアントで使用できます。

13
Darin Dimitrov