如何在C#中创build一个ActiveX控件(COM)?

我正在尝试创build一个ActiveX控件。 我使用Visual Studio 2010 (.NET 4)。 我需要创build一个COM对象(在C#中),不知道如何开始(使用什么types的项目等)

好的,我find了解决办法,我会写在这里为了共同的利益。

  1. 以pipe理员身份启动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文件的项目中的属性文件夹下,将ComVisible设置为true。
  10. 在项目属性菜单中,在生成选项卡中标记“注册COM互操作”
  11. build立这个项目

现在你可以使用它的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()

和输出将是:

我为了生计启动脚本

创build步骤

  1. 以pipe理员身份启动Visual Studio 2013
  2. 安装Visual Studio扩展Microsoft Visual Studio安装程序项目
  3. 创build一个类库项目(WinFormActivex)
  4. 创build您的示例窗口窗体(MainWindow)
  5. 创build一个新的组件接口(ILauncher)
  6. 创build一个新的安全接口(IObjectSafety)
  7. 创build实现接口的组件控件(Launcher)并启动窗口。
  8. 检查所有GUID是否由您生成
  9. 检查项目是否标记为COM
  10. 使用WinFormActivex的主输出创build安装项目(LauncherInstaller),其属性为Register = vsdrpCOM
  11. 安装LauncherInstaller
  12. 在资源pipe理器(test.html)中运行你的testing页面

MainWindow你可以创build一个正常的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; } 

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> 

参考

  • 堆栈溢出问题我总是用作参考
  • Activex标签你应该阅读
  • 旧的微软指南
  • 关于创build具有安全选项的acrivex控制的文章
  • 关于创build窗口的文章

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

确保程序集已经成为可见的:

替代文字

最后使用regasm.exe注册它:

 regasm.exe /codebase mylib.dll 

现在,该程序集将作为COM对象公开,并且您声明的types可以由任何支持COM的客户端使用。