我在 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主机的名称:
BuiltIn
的引用。 为了可靠地获得对 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/