【问题标题】:Outlook - get email address from Display Name. Works in Python, not COutlook - 从显示名称获取电子邮件地址。在 Python 中工作,而不是 C
【发布时间】:2016-01-17 21:38:32
【问题描述】:

我正在尝试将一些代码从 Python 转换为 C 和 OLE。该代码正在从 Outlook 显示名称获取电子邮件地址。

Python 代码的工作原理如下:

    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)

反过来,它基本上是VBA code on MSDN 的python 化版本。

但是,在 C 和 OLE 中,我只是不明白,我只能在 MSDN 和其他论坛上找到带有 MFC 示例(我不感兴趣)的 C#、VBA 和 C++,以及使用专有的建议框架。

到目前为止,我在 C 中拥有的东西。 outlookapp 已成功初始化为 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);
    }
}

代码在“Can not CreateRecipient()”printf 消息中终止,错误 0x800706F4 对应于 “空引用指针已传递给存根。”

AutoWrap 也会写入自己的消息:IDispatch::Invoke("CreateRecipient"=0000210a) failed w/err 0x800706f4

来自 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; 
} 

最终目标是将 Outlook 中的地址数据输入 Excel,并且我已经使用 OLE 实现了 Excel 自动化。真的很高兴有任何想法 - 我真的试图找到这方面的信息,但没有找到太多关于 Outlook 在这个级别上实际工作的信息。

【问题讨论】:

  • @HansPassant 希望您有时间简要了解一下。
  • AutoWrap 应该返回错误码,使用 VS 中的错误查找工具查找
  • @Matt,OK 会试试的。 “一个空引用指针被传递给存根。”哎呀。
  • @Matt, 0x800706F4 = 一个空引用指针被传递给存根。
  • 您必须调试 AutoWrap 函数以找出哪个参数不应为 NULL。顺便说一句,在原生 C++ 中,您可以直接调用 COM 中的调用函数,不需要使用调用。我找到了一个关于 execl 的例子,而不是 Outlook:wilmott.com/messageview.cfm?catid=10&threadid=26137。但想法是一样的。

标签: c++ c outlook com ole


【解决方案1】:

正如 Hans Passant 所见,我只是在这一行输入了 &x 而不是 x

HRESULT hr = AutoWrap(DISPATCH_METHOD, &result, pNS, L"CreateRecipient", 1, &x);

::

HRESULT hr = AutoWrap(DISPATCH_METHOD, &result, pNS, L"CreateRecipient", 1, x);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 2013-12-01
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多