c++ - 从 VC++ 应用程序使用 VSTO 插件触发删除 Outlook 电子邮件附件

标签 c++ email visual-c++ outlook com

我正在尝试从 VC++ 应用程序中删除 Outlook 中的电子邮件。我有一个 Outlook 插件,它正在 Outlook 中加载并在系统中注册。触发电子邮件删除的 VC++ 应用程序调用 CoCreateInstance() 并成功返回。

HRESULT hr;
IFoo* pISL;
CoInitialize(NULL);

LPOLESTR lpoleStr;
StringFromCLSID(__uuidof(Foo), &lpoleStr);

hr = CoCreateInstance(
    __uuidof(Foo),         // CLSID of coclass
    NULL,                    // not used - aggregation
    CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER,    // type of server
    __uuidof(IFoo),          // IID of interface
    (void**)&pISL);        // Pointer to our interface pointer

if (SUCCEEDED(hr))
{
    //fire event
    BSTR bstr = SysAllocString(params->szObjectPath);
    pISL->FooMethod(bstr);
    pISL->Release();
    SysFreeString(bstr);
}
else
{
    // Couldn't create the COM object. hr holds the error code.
}

CoUninitialize();

然后我使用返回的 COM 对象来调用我请求的 COM 接口(interface)中的方法。这些方法触发应由 Outlook 插件监听的事件。

private void RegisterConnectionPoint()
{
    Logger.Log("RegisterConnectionPoint():");

    // Call QueryInterface for IConnectionPointContainer
    Foo foo = new Foo();
    IConnectionPointContainer icpc = (IConnectionPointContainer)foo;

    // Find the connection point for the
    // _IFoo source interface
    Guid IID_IFoo = typeof(_IFoo).GUID;

    icpc.FindConnectionPoint(ref IID_IFoo, out icp);

    // Pass a pointer of the host to the connection point
    icp.Advise(this, out cookie);
}

我的问题是 Outlook 插件从不接收来自 COM 对象的事件。我认为这可能是由于插件没有正确注册到 COM 对象,或者有两个 COM 对象,一个用于 VC++ 应用程序,一个用于 Outlook 插件。

我的问题是

  1. 创建 Outlook VSTO 插件的基本概念是否可行,该插件在从 COM 服务器接收事件时删除电子邮件,而 COM 服务器的事件是从单独的进程触发的?
  2. 如果第一个问题的答案是"is",那么任何人都可以看到我做错了什么吗?

调试 VC++ 应用程序端我得到了这段代码,它似乎是生成的 ATL 代码(我没有编写所有代码,所以有时我在猜测):

int cConnections = m_vec.GetSize();

for (int iConnection = 0; iConnection < cConnections; iConnection++)
{
    pThis->Lock();
    CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
    pThis->Unlock();

    IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

    if (pConnection)
    {
        CComVariant avarParams[1];
        avarParams[0] = attachmentPath;
        avarParams[0].vt = VT_BSTR;
        CComVariant varResult;

        DISPPARAMS params = { avarParams, NULL, 1, 0 };
        hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &varResult, NULL, NULL);
    }
}

问题是 m_vec.GetSize() 返回 0。所以似乎没有“连接”。这意味着我创建的 COM 对象实例与 Outlook 插件使用的实例不同,或者插件未正确注册。

最佳答案

所以@Dmitry 提供的链接正是我所需要的。通过使用运行对象表 (ROT),我能够获得对 Outlook 加载的 Outlook 插件的引用。因此允许我调用其中的方法来删除邮件附件。

需要进行一些更改,包括:

  1. 将加载项的注册移动到 ThisAddin_Startup() 作为默认 OutlookAddin 类使用静态构造函数,因此我无法在构造函数中引用加载项。
  2. 我还必须将我的代码移动到用户 session 进程,因为这篇文章 COMException (0x800401E3): Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE)) with scheduled task说明服务不支持从 ROT 检索 COM 对象。这只是我认为我应该补充的一点,因为它可能会阻碍人们尝试与我相同的事情。

此外,我在此处找到了 ROT 查看器工具 http://alax.info/blog/1444很有用,因为您可以检查您的插件是否真的注册到 ROT。

希望这对人们有所帮助。

关于c++ - 从 VC++ 应用程序使用 VSTO 插件触发删除 Outlook 电子邮件附件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40999843/

相关文章:

email - 来自 ggpht.com GoogleImageProxy 代理的多次调用

c++ - 收到基于模板类及其子类函数调用的错误

c++ - 无法使用文件中的 sourceCpp

c++ - 模板和 std::pair 列表初始化

使用 corona sdk 验证电子邮件地址

validation - 如何将电子邮件建议传递到 Azure AD B2C 注册页面

opencv - 卸载 winmmbase.dll visual studio 2015

c++ - 如何为模板方法创建别名

c++ - 如何创建文件的 md5 或 sha1 校验和而不将其内容加载到内存?

c++ - 创建大小小于 1MiB 的静态二进制文件,可以从 S3 或 GCS 下载文件