我正在尝试创建一个Outlook 2013插件,它将从指定位置加载其他托管插件。基本上是一个加载器存根,它知道如何找到这些其他插件,加载它们的组件并注册。
这是一个简单的概念证明:
using System;
using System.Linq;
using System.Windows.Forms;
using System.ComponentModel;
using System.Reflection;
using Microsoft.Office.Tools;
using Microsoft.Office.Core;
using Microsoft.Office.Tools.Ribbon;
[Microsoft.VisualStudio.Tools.Applications.Runtime.StartupObject(0)]
public class TestAddin : IAddInExtension, IExtension, EntryPoint, ISupportInitialize, IComponent, IDisposable, IBindableComponent
{
private List<EntryPoint> entrypoints = new List<EntryPoint>();
public TestAddin(Factory factory, IServiceProvider serviceProvider)
{
Assembly asm = LoadAddinAssembly();
foreach (var type in asm.GetTypes())
{
var attr = type.GetCustomAttributes(false).OfType<Microsoft.VisualStudio.Tools.Application.Runtime.StartupObjectAttribute>().FirstOrDefault();
if (attr != null)
{
var ep = Activator.CreateInstance(
type, factory, serviceProvider)
as Microsoft.Office.Tools.EntryPoint;
if (ep != null)
{
entrypoints.Add(ep);
}
}
}
}
public void BeginInit()
{
foreach (var inst in entrypoints)
inst.BeginInit();
}
// Implement the rest of the interface methods similar to BeginInit above
}
Outlook构造我的类,我的类加载其他插件程序集并创建入口点,然后outlook调用以下3个passthrough方法,然后我调用另一个插件:
他们都没有创建任何错误,但在此之后,没有任何直通方法被调用,而且我正在尝试加载的插件永远不会做任何事情。
什么是暴露给Outlook的官方插件我需要通过什么?或者甚至可以做这样的事情?
答案 0 :(得分:0)
看起来父服务提供商会跟踪它创建的每个EntryPoint。如果你像这样抓住IHostItemProvider:
<?php
//Kill a sudo session if one exists.
exec('sudo -k');
//Run sudo without authenticating
$output = exec('sudo echo "foo"');
var_dump($output); //string(0) ""
//Provide the password and pipe it into sudo.
$output = exec('echo "password" | sudo -S echo "foo" 2> /dev/null');
var_dump($output); //string(3) "foo"
?>
你可以使用反射设置&#34; _entryPoints&#34; (这是EntryPoint [])修改入口点列表。然后,调用代码将它们视为普通的EntryPoints,无需在本地跟踪它们以进行直通调用。
另一个关键细节是_entryPoints [0]似乎是唯一一个可以注册UI的某些方面,因此最好从OutlookAddInBase派生(因为它实现了UI初始化逻辑)并对其进行直通调用CreateRibbonExtensibilityObject()和CreateRibbonObjects()的第一个入口点。
此外,必须在清单中定义Ribbons和FormRegions,我还没有找到任何方法,所以它还需要创建一堆通过反射连接起来的直通存根。
非常脆弱的解决方案,但它似乎现在有效(直到微软改变内部)。而且由于_entryPoints [0]如此重要,看起来每个加载器存根只能加载一个插件。
答案 1 :(得分:0)
如果未加载这些其他加载项,您可以通过Application.COMAddIns集合执行此操作。获取要加载的加载项的COMAddIn对象,并设置COMAddIn.Connect = True。
另请参阅此内容以获得调用另一个加载项的方法的受支持方式: