【问题标题】:How to call a VSTO AddIn method from a separate C# project?如何从单独的 C# 项目调用 VSTO AddIn 方法?
【发布时间】:2009-02-13 07:06:19
【问题描述】:

我有一个 C# Excel 插件项目“MyExcelAddIn”,它有一个公共方法 Foo() 来做一些复杂的事情。出于测试目的,插件还定义了一个工具栏按钮,该按钮连接到 Foo(),因此我可以对此进行测试并验证单击该按钮是否会调用 Foo() 并执行我希望它执行的操作。这很好。

现在我想从 C# Windows 窗体项目中调用此方法。在 Windows 窗体项目中,我可以创建一个 Excel 实例并使其可见,并验证我的 VSTO 加载项是否正在运行,因为我可以看到该按钮并且它工作正常。但我不知道如何从 Windows 窗体项目中以编程方式调用 Foo()。我用谷歌搜索了一下,得到了“MyExcelAddIn”COMAddIn 对象,但不知道如何调用 Foo()。

看起来像这样:

// Create Excel and make it visible
Application excelApp = new Application();
excelApp.Visible = true;

// I know my VSTO add-in is running because I can see my test button
// Now get a reference to my VSTO add-in
Microsoft.Office.Core.COMAddIns comAddIns = _excelApp.COMAddIns;
object addinName = "MyExcelAddIn";
Microsoft.Office.Core.COMAddIn myAddin = comAddIns.Item(ref addinName);
// This works, but now what? How do I make a call on myAddin?
// Note that myAddin.Object is null...

所以我想知道如何从我的 Windows 窗体应用程序调用 Foo()。请注意,我可以完全控制 Windows 窗体应用程序和加载项,我怀疑我必须对它们进行更改(尤其是加载项),但我不知道如何执行此操作。

请注意,这是一个 VS2008 C# 应用程序,我使用的是 Excel 2003。

【问题讨论】:

    标签: c# .net visual-studio-2008 vsto add-in


    【解决方案1】:

    如果您正在构建应用程序级插件,我相信这可能是您的答案:MSDN VSTO Article

    涉及两个步骤:(摘自文章)

    1. 在您的加载项中,将对象公开给其他解决方案。
    2. 在另一个解决方案中,访问您的外接程序公开的对象,并调用该对象的成员。

    另一种解决方案可能是:(再次来自文章)

    • 在与加载项不同的进程中运行的任何解决方案(这些类型的解决方案也称为进程外客户端)。其中包括自动化 Office 应用程序的应用程序,例如 Windows 窗体或控制台应用程序,以及在不同进程中加载​​的加载项。

    【讨论】:

    • 这应该是答案!
    【解决方案2】:

    我正在使用 SendMessage Win32 API 来执行此操作。我的 C# 插件创建了一个“NativeWindow”,它具有 WinForm 应用程序可以找到的唯一窗口标题。

    【讨论】:

    • 怎么做?任何教程?我在哪里可以得到这个 SendMessage Win32 API?
    【解决方案3】:

    我假设您的方法 Foo 以某种方式与 Excel 交互。否则,您只需使用 Foo 方法添加对包含该类的程序集的引用,然后从那里调用它,而无需实例化 Excel。

    我能想到的唯一其他方法是通过 excelApp 对象获取对您的 CommandBarButton 的引用。 CommandBarButton 有一个名为 Execute 的方法,它类似于单击按钮。像这样的:

            Excel.Application excelApp = new Excel.Application(); 
            CommandBarButton btn = excelApp.CommandBars.FindControl(...) as CommandBarButton;
            btn.Execute();
    

    【讨论】:

    • 谢谢,这是一个巧妙的技巧,但我一直在寻找一种更通用的方法,因为除了这个简单的测试应用程序之外,我们还有很多方法,当然有些带有参数,所以不想创建一个每个按钮的隐藏按钮(以及如何处理参数)。
    【解决方案4】:

    对于其他发现此内容的人来说,这就是我所做的:

            object addInName = "AddinName";
            var excelApplication = (Microsoft.Office.Interop.Excel.Application)Marshal.GetActiveObject("Excel.Application");
            COMAddIn addIn = excelApplication.COMAddIns.Item(ref addInName);
    
            addIn.Object.AddinMethodName(params);
    

    还必须在 COM 下添加对 Microsoft.Office.Core 的引用,在 Assemblies 下添加对 Excel.Interop 的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-10
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      相关资源
      最近更新 更多