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

Eya*_*yal 48 com visual-studio-2010 c#-4.0

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

Eya*_*yal 70

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

  1. 以管理员身份启动VS2010.
  2. 打开一个类库项目(exmaple - 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.");

        }

    }
}
Run Code Online (Sandbox Code Playgroud)

和使用COM的VB脚本:

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

输出将是:

我推出以生活为目的的脚本

  • 此外,如果您构建了程序集并且无法使用它:("无法创建对象"错误)http://stackoverflow.com/questions/1208180/classic-asp-using-com-on-x64-windows-server -2008-and-iis7 http://stackoverflow.com/questions/1281052/classic-asp-using-com-net-interop-64-bit-windows-server-2008-iis-7-server-crea/1343271# 1343271 (2认同)

Giu*_*cin 16

创作步骤

  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. 使用属性创建具有WinFormActivex主要输出的安装项目(LauncherInstaller) Register = vsdrpCOM
  11. 安装LauncherInstaller
  12. 在资源管理器中运行测试页(test.html)

MainWindow 您可以创建一个普通的Form,这里是预生成的.

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;
}
Run Code Online (Sandbox Code Playgroud)

ILauncher

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

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);
    }
Run Code Online (Sandbox Code Playgroud)

启动器 请在此处生成您的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
 }
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

参考


Dar*_*rov 13

You could use a class library project. Declare a type with methods that will be exposed as a COM object.

Make sure that the assembly has been made COM-visible:

替代文字

And finally register it using regasm.exe:

regasm.exe /codebase mylib.dll
Run Code Online (Sandbox Code Playgroud)

Now the assembly is exposed as a COM object and the type you declared can be consumed by any client that supports COM.