Richard T Slade
Richard T Slade

Reputation: 35

Trigger deletion of Outlook email attachment using VSTO AddIn from VC++ app

I am attempting to delete an email in Outlook from a VC++ app. I have an Outlook Addin that is loading in Outlook and registered with the system. The VC++ app to trigger the deletion of the email makes a call to CoCreateInstance() and returns successfully.

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();

I am then using the COM object returned to call the methods in the COM interface I requested. These methods fire events that should be listened to by the 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);
}

My problem is the Outlook Addin never receives the events from the COM object. I think it may be due to the Addin not correctly registering with the COM object, or that there are two COM objects one for the VC++ app and one for the Outlook Addin.

My questions are

  1. Is the basic concept of creating a Outlook VSTO Addin that deletes emails upon receiving an event from a COM server whose events are triggered from a separate process feasible?
  2. If the answer is 'yes' to the first question can anyone see what I am doing wrong?

Debugging the VC++ app side I get to this code which it seems is generated ATL code (I haven't written all the code so am guessing sometimes):

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);
    }
}

The problem is m_vec.GetSize() returns 0. So it seems there are no 'connections'. Which would imply I am either creating a different instance of the COM object than the one used by the Outlook Addin or the Addin is not registering correctly.

Upvotes: 0

Views: 99

Answers (1)

Richard T Slade
Richard T Slade

Reputation: 35

So the link supplied by @Dmitry was what I needed. By using the Running Object Table (ROT) I was able to get a reference to the Outlook addin loaded by Outlook. So allowing me to call the methods inside it to delete the mail attachment.

Some changes were required including:

  1. Moving registration of the addin to ThisAddin_Startup() as the default OutlookAddin class uses a static constructor so I was not able to reference the Addin inside the constructor.
  2. I also had to move my code to a user session process as this post COMException (0x800401E3): Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE)) with scheduled task explains retrieving an COM object from the ROT is not supported for services. This was just a point I thought I should add as it could stump people trying the same thing I was.

Additionally I found the tool ROT viewer found here http://alax.info/blog/1444 useful as you can check if you addin is actually registering to the ROT.

Hope this helps people.

Upvotes: 1

Related Questions