简体   繁体   English

我如何获得* actual *主机应用程序实例?

[英]How do I get the *actual* host application instance?

I have this code in a C# add-in for the VBE (emphasis "VBE": it's not a MS-Office add-in): 我在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");
    }

Where TApplication is a MS-Office interop Application class, for example, a Microsoft.Office.Interop.Excel.Application type; 其中TApplication是MS-Office互操作Application类,例如, Microsoft.Office.Interop.Excel.Application类型; here the applicationName parameter would be "Excel" for, well, Excel. 这里的applicationName参数对于Excel来说就是“Excel”。

The problem is that Marshal.GetActiveObject seems to only ever return the first instance created, and that's not necessarily the instance that's hosting the current VBE environment, and this causes issues . 问题是Marshal.GetActiveObject似乎只返回创建的第一个实例,并且不一定是托管当前VBE环境的实例, 这会导致问题

How can I get ahold of the actual host application instance? 如何获得实际的主机应用程序实例?

For the sake of slaying a zombie, you can get the name of the VBE's host by: 为了杀死一个僵尸,你可以通过以下方式获得VBE主机的名称

  • Inspecting the caption of the CommandBarButton that takes you to the host. 检查将您带到主机的CommandBarButton标题。 The button is on the Standard Toolbar, but also in the View Menu. 该按钮位于标准工具栏上,但也位于“视图”菜单中。

  • Inspecting the names of the references. 检查参考文献的名称。 Typically the first reference that isn't VBA but is BuiltIn . 通常,第一个不是VBA的引用是BuiltIn

  • Inspecting the Application.Name property of document component's Properties collection. 检查文档组件的Properties集合的Application.Name属性。

And to reliably get a reference to the VBE's host, you have to use the Properties collection of the document-type components. 要可靠地获取对VBE主机的引用,您必须使用文档类型组件的Properties集合。 For example, once you know that the name of the host is "Microsoft Excel", you just need to find the Workbook document-component (typically named ThisWorkbook), then you can get the host from the component's Properties collection. 例如,一旦您知道主机的名称是“Microsoft Excel”,您只需要找到工作簿文档组件(通常名为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");
            }

But not all vbProjects have document-type components, so for such projects you'll have to resort to the GetActiveObject approach. 但并非所有vbProject都具有文档类型组件,因此对于此类项目,您将不得不求助于GetActiveObject方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何获得DependancyProperty的实际值? - How do I get the actual value of a DependancyProperty? 如何使用控制台应用程序中的通用主机从 appsettings 中获取连接字符串? - How do I get the connection string out of appsettings using a generic host in console application? 如何获取复选框的实际名称而不是datarowview - How do I get actual name of checkbox instead of datarowview 如何获取实际的Monitor名称? 如解决方案对话框中所示 - How do I get the actual Monitor name? as seen in the resolution dialog TLD授权记录。 如何获得实际的扩展名? - TLD Delegation Records. How do I get the actual extension? 我如何知道分配给线程的实际时间片? - How do I get to know the actual time slice given to a thread? 如何在VSPackage中获取IVsExpansionClient的实例? - How do I get an instance of IVsExpansionClient in VSPackage? 如何在运行时获取实例的引用? - How do I get a reference to a instance at runtime? 如何从VB.NET中的事件获取实际的EventHandler委托实例? - How can I get an actual EventHandler delegate instance from an event in VB.NET? 如何重新启动单个实例winforms应用程序 - how do I restart a single instance winforms application
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM