I am trying to convert some code from Python to C and OLE. The code is getting an email address from the Outlook Display Name.
The Python code works and looks like this:
recipient = self._outlook.Session.CreateRecipient(name)
recipient.Resolve()
if self._first:
print(inspect.getmembers(recipient))
self._first = False
print(recipient.Resolved)
print(recipient.AddressEntry)
if 'EX' == recipient.AddressEntry.Type:
exchange_user = recipient.AddressEntry.GetExchangeUser()
email = exchange_user.PrimarySmtpAddress
elif 'SMTP' == recipient.AddressEntry.Type:
email = recipient.AddressEntry.Address
print(email)
It, in turn, is basically a python-ized version of the VBA code on MSDN.
However, in C and OLE I just don't get it and I can only find C#, VBA and C++ with MFC examples (which I am not interested in) on MSDN and other forums, as well as suggestions to use proprietary frameworks.
What I have in C so far. outlookapp
is successfully initialized with CoCreateInstance()
.
IDispatch *pNS = NULL;
{
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = SysAllocString(L"MAPI");
VARIANT result;
VariantInit(&result);
AutoWrap(DISPATCH_METHOD, &result, outlookapp, L"GetNamespace", 1, x);
pNS = result.pdispVal;
SysFreeString(x.bstrVal);
VariantClear(&x);
}
// Log on by using a dialog box to choose the profile.
{
VARIANT vtShowDialog;
vtShowDialog.vt = VT_BOOL;
vtShowDialog.boolVal = VARIANT_TRUE;
VARIANT vtNewSession;
vtNewSession.vt = VT_BOOL;
vtNewSession.boolVal = VARIANT_TRUE;
if (FAILED(AutoWrap(DISPATCH_METHOD, NULL, pNS, L"Logon", 4, vtNewSession,
vtShowDialog, vtMissing, vtMissing))) {
printf("Logon failed.\n"); Sleep(15000); ExitProcess(1);
}
}
printf("Done logging in to Outlook\n");
IDispatch *recipient = NULL;
{
VARIANT x;
x.vt = VT_BSTR;
x.bstrVal = SysAllocString(L"John Doe");
VARIANT result;
VariantInit(&result);
HRESULT hr = AutoWrap(DISPATCH_METHOD, &result, pNS, L"CreateRecipient", 1, &x);
if (FAILED(hr)) {
printf("Can not CreateRecipient(), error: %x\n", hr); Sleep(60000); ExitProcess(1);
}
recipient = result.pdispVal;
}
{
VARIANT result;
VariantInit(&result);
HRESULT hr = AutoWrap(DISPATCH_METHOD, &result, recipient, L"Resolve", 0);
if (FAILED(hr)) {
printf("Can not call Resolve()\n");
Sleep(3000); ExitProcess(1);
}
}
The code dies on the "Can not CreateRecipient()" printf message with the error 0x800706F4 which corresponds to "A null reference pointer was passed to the stub."
AutoWrap also writes its own message: IDispatch::Invoke("CreateRecipient"=0000210a) failed w/err 0x800706f4
It comes from this code in AutoWrap:
// Make the call
hr = pDisp->Invoke(
dispID,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
autoType,
&dp,
pvResult,
NULL,
NULL
);
if (FAILED(hr))
{
wprintf(L"IDispatch::Invoke(\"%s\"=%08lx) failed w/err 0x%08lx\n",
ptName, dispID, hr);
return hr;
}
The end objective is to feed address data from Outlook into Excel, and I have Excel automation with OLE already working. Really happy for any ideas - I have really tried to find information about this but not found much on how Outlook actually works on this level.
As Hans Passant saw, I just typed &x
instead of x
in this line:
HRESULT hr = AutoWrap(DISPATCH_METHOD, &result, pNS, L"CreateRecipient", 1, &x);
::
HRESULT hr = AutoWrap(DISPATCH_METHOD, &result, pNS, L"CreateRecipient", 1, x);