我在 VBE 的 C# 加载项中有此代码(强调“VBE”:它是 而不是 是 MS-Office 加载项):

public abstract class HostApplicationBase<TApplication> : IHostApplication
    where TApplication : class
{
    protected readonly TApplication Application;
    protected HostApplicationBase(string applicationName)
    {
        Application = (TApplication)Marshal.GetActiveObject(applicationName + ".Application");
    }

其中 TApplication 是 MS-Office 互操作 Application 类,例如 Microsoft.Office.Interop.Excel.Application 类型;这里的 applicationName 参数将是“Excel”,用于 Excel。

问题是 Marshal.GetActiveObject 似乎只返回创建的第一个实例,这不一定是托管当前 VBE 环境和 this causes issues 的实例。

我怎样才能获得实际的主机应用程序实例?

最佳答案

为了杀死僵尸,您可以通过以下方式获取VBE主机的名称:

  • 检查将您带到主机的 CommandBarButton 的标题。该按钮位于标准工具栏上,但也在 View 菜单中。
  • 检查引用的名称。通常第一个不是 VBA 而是 BuiltIn 的引用。
  • 检查文档组件的 Properties 集合的 Application.Name 属性。

  • 为了可靠地获得对 VBE 主机的引用,您必须使用文档类型组件的 Properties 集合。例如,一旦知道宿主的名称是“Microsoft Excel”,只需找到Workbook 文档组件(通常命名为ThisWorkbook),然后就可以从组件的Properties 集合中获取宿主。
                var appProperty = vbe.VBProjects
                    .Cast<VBProject>()
                    .Where(project => project.Protection == vbext_ProjectProtection.vbext_pp_none)
                    .SelectMany(project => project.VBComponents.Cast<VBComponent>())
                    .Where(component => component.Type == vbext_ComponentType.vbext_ct_Document
                    && component.Properties.Count > 1)
                    .SelectMany(component => component.Properties.OfType<Property>())
                    .FirstOrDefault(property => property.Name == "Application");
                if (appProperty != null)
                {
                    Application = (TApplication)appProperty.Object;
                }
                else
                {
                    Application = (TApplication)Marshal.GetActiveObject(applicationName + ".Application");
                }
    

    但并不是所有的 vbProjects 都有文档类型的组件,所以对于这样的项目,你必须求助于 GetActiveObject 方法。

    关于c# - 我如何获得*实际*主机应用程序实例?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32953450/

    10-17 01:34