2016-12-06 47 views
0

我试图从VC++应用程序中删除Outlook中的电子邮件。我有一个在Outlook中加载并在系统中注册的Outlook Addin。触发删除电子邮件的VC++应用程序调用CoCreateInstance()并成功返回。从VC++应用程序中使用VSTO AddIn触发删除Outlook电子邮件附件

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接口中的方法。这些方法触发Outlook Addin应该侦听的事件。

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 Addin从不接收来自COM对象的事件。我认为这可能是由于Addin未正确注册COM对象,或者有两个COM对象用于VC++应用程序和一个用于Outlook Addin。

我的问题是

  1. 正在创造一个展望VSTO外接一个删除后从其事件从一个单独的进程可行触发一个COM服务器接收邮件事件的基本概念?
  2. 如果第一个问题的答案是'是',任何人都可以看到我做错了什么?

调试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 Addin使用的实例或Addin未正确注册。

+0

对象是否在proc中创建?你确定你连接到一个COM对象实现b外部exe文件吗? –

+0

@DmitryStreblechenko第一个代码示例是来自VC++应用程序的代码,我希望能够与Outlook Addin进行通信。所以这就是创建COM对象的地方。不知道这是否回答yur问题:) –

+0

这不是我的意思 - COM对象在哪里实现?该exe或外挂?它是由exe实现的单例COM对象? –

回答

1

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

一些变化,包括:

  1. 移动插件的登记ThisAddin_Startup()作为默认OutlookAddin类使用静态构造函数,所以我没能引用加载项的构造函数中。
  2. 我还必须将我的代码移动到用户会话进程,因为此帖COMException (0x800401E3): Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE)) with scheduled task说明从服务中不支持从ROT检索COM对象。这只是我认为我应该补充的一点,因为它可能会让人们尝试与我一样的事情。

此外,我发现在这里找到的工具ROT查看器http://alax.info/blog/1444有用,因为你可以检查你的插件是否实际上注册到ROT。

希望这有助于人们。

相关问题