如何将运行.NET应用程序对象公开为com for Vba.getObject?(不重复)



我有 no 问题编写.net winforms可执行文件,将其中的一些类公开到com中,并在excel vba中使用excel vba中的内容:

Set myVbaObj = VBA.CreateObject("MyNameSpace.MyClassName")
myVbaObj.SayHi "I hope somebody will answer this question."

在我的.NET类中com上可见的地方:

using System.Runtime.InteropServices;
namespace MyNameSpace
{
  [Guid("GUID created by Visual Studio->Tools->Create GUID")]
  public interface IMyClassName
  {
    void SayHi(string Msg);
  }
  [ComVisible(true)]
  [Guid("Other GUID created by Visual Studio->Tools->Create GUID")]
  [ProgId("MyNameSpace.MyClassName")]
  [ClassInterface(ClassInterfaceType.None)]
  public class MyClassName : IMyClassName
  {
    public MyClassName()
    {
      RegistrationServices rs;
      try
      {
        // Class constructor registers itself for COM
        rs = new RegistrationServices();
        if (!rs.RegisterAssembly(Assembly.GetExecutingAssembly(),
                                AssemblyRegistrationFlags.SetCodeBase))
        {
          throw new Exception
          ("Error registering MyClassName COM component.");
        }
      }
      catch (Exception ex)
      {
        throw new Exception(string.Format(
          "Error in {0} constructor:rn{1}",
          this.GetType().Name, ex.Message));
      }
      // End of MyClassName constructor
    }
    [ComVisible(true)]
    public void SayHi(string Msg)
    {
      try
      {
        MessageBox.Show(string.Format(
          "Hi from Excel: '{0}'.", Msg));
      }
      catch (Exception ex)
      {
        throw new Exception(string.Format(
          "Error in {0}.SayHi:rn{1}",
          this.GetType().Name, ex.Message));
      }
      // End of SayHi()
    }
  }
}

但是,我想像excel一样露出.exe,以便我可以参考.NET应用程序的运行实例并进行交互。在Excel VBA中,这是通过" getObject"发生的:

Set myVbaObj = VBA.GetObject( , "MyNameSpace.Application")
Set xlApp = VBA.GetObject( , "Excel.Application")
print xlApp.caption

编辑:放入最初省略的接口定义中。

,所以这个家伙有一篇非常好的文章,回答了我的问题。尽管他详细介绍了,但明显的最低要求是在运行对象表(rot(中注册对象。我的实现看起来像下面。试图从文章中实现处置函数时,我会遇到错误(我想在其他人浪费时间之前回答(。

添加此类定义(从文章中直接复制/粘贴 - "朋克"可能是未知的指针(:

using System.Runtime.InteropServices;
public class Ole32
{
  [DllImport("Ole32.Dll")]
  public static extern int CreateBindCtx(int reserved,
  out UCOMIBindCtx bindCtx);
  [DllImport("oleaut32.dll")]
  public static extern int RegisterActiveObject
      ([MarshalAs(UnmanagedType.IUnknown)] object punk,
          ref Guid rclsid, uint dwFlags, out int pdwRegister);
  // End of Ole32 class definition
}

对类构造函数进行这些更改,并添加模块级别变量:

private int _DwRegister;
public MyClassName()
{
  RegistrationServices rs;
  try
  {
    // Class constructor registers itself for COM
    rs = new RegistrationServices();
    if (!rs.RegisterAssembly(Assembly.GetExecutingAssembly(),
                            AssemblyRegistrationFlags.SetCodeBase))
    {
      throw new Exception
      ("Error registering MyClassName COM component.");
    }
    Guid guid = Marshal.GenerateGuidForType(typeof(SmartDesigner));
    Ole32.RegisterActiveObject(this, ref guid, 0, out _DwRegister);
  }
  catch (Exception ex)
  {
    throw new Exception(string.Format(
      "Error in {0} constructor:rn{1}",
      this.GetType().Name, ex.Message));
  }
  // End of MyClassName constructor
}

在这一点上,一旦类是一种或另一种方式实例化(我刚刚在我的应用程序主winform的"显示"事件中创建了一个实例(,您应该能够通过vba.getObject访问它。

相关内容

  • 没有找到相关文章

最新更新