none
How to parse contact group as an attachment in outlook? RRS feed

  • Question

  • As you konw, we can create a contact group and send a contact group using outlook.

    I am developping a outlook plug-in, want to prase contact group which was sent as an attachment( in .msg file ).

    How to parse it and get each contact information?

    Thank you very much if you give me some help.

    Here is how I parse contact, but it does not work for contact group.

    code:

    CComBSTR bstr = emailData1.GetAttachmentData()[0].GetSourcePath().c_str();
    CComVariant comVarOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
     g_pOutlookObj->get_App()->CreateItemFromTemplate(bstr, comVarOptional, &m_spNewMailItem);

    MailItemUtility::get_contactcontent(m_spNewMailItem);

    static HRESULT get_contactcontent(CComPtr<IDispatch> lpDisp)
     {
      HRESULT hr =S_FALSE ;
      if( lpDisp != NULL )
      {
       CComPtr<Outlook::_ContactItem> spCurMailItem = 0;
       hr = lpDisp->QueryInterface(Outlook::IID__ContactItem, (void**)&spCurMailItem);
       if(SUCCEEDED(hr) && spCurMailItem)
       {
        BSTR Subject;
        BSTR eaddress;
        BSTR Body;
        BSTR firstname;
        BSTR fullname;
        BSTR mailattr;
        spCurMailItem->get_Subject(&Subject) ;
        
        spCurMailItem->get_Body(&Body);
        spCurMailItem->get_Email1Address(&eaddress);
        spCurMailItem->get_FirstName(&firstname);
        spCurMailItem->get_FullName(&fullname);
        spCurMailItem->get_MailingAddress(&mailattr);
        return hr ;
       }
       else
       {
        DP((L"test not a contact!"));
        return hr ;
       }
      }

     }


    Thursday, December 8, 2016 6:53 AM

Answers

  • Save the attachment as an MSG file (Attachment.SaveAsFile), then open the MSG file using Namespace.GetSharedItem - you will get back DistListItem object.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Sunday, December 11, 2016 10:19 PM

All replies

  • Save the attachment as an MSG file (Attachment.SaveAsFile), then open the MSG file using Namespace.GetSharedItem - you will get back DistListItem object.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Sunday, December 11, 2016 10:19 PM
  • Thank you very much! But we still have some problems.

    Though DistListItem object we only get each contact's name and email address; can't get earch contact's other properties, such as CompanyName,JobTitle,HomeTelephoneNumber,BusinessTelephoneNumber,MobileTelephoneNumber.

    Deer Dmitry, could you please help us deal this problem? Thank you very much!

    Leo

    Tuesday, December 27, 2016 8:41 AM
  • DistListItem object exposes the GetMember method which returns a Recipient object. You can use Recipient.AddressEntry.GetContact method to get a ContactItem object if the member is contact based (and not, for example, from GAL).

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Tuesday, December 27, 2016 10:15 PM
  •    if(SUCCEEDED(hr) && spCurMailItem)

       {
        BSTR Subject;
        BSTR eaddress;
        BSTR Body;
        BSTR firstname;
        BSTR fullname;
        BSTR mailattr;
        spCurMailItem->get_Subject(&Subject) ;
        
        spCurMailItem->get_Body(&Body);
        spCurMailItem->get_Email1Address(&eaddress);
        spCurMailItem->get_FirstName(&firstname);
        spCurMailItem->get_FullName(&fullname);
        spCurMailItem->get_MailingAddress(&mailattr);
        return hr ;
       }
       else
       {
        DP((L"test not a contact!"));
        return hr ;
       }

    BTW, the above code is leaking BSTRs.  You should change it it use CComBSTR or include calls to SysFreeString
    Wednesday, December 28, 2016 12:39 PM
  • Thank you friend, I will pay attation when begin project programing.

    Thank you!

    Thursday, December 29, 2016 3:32 AM
  • CComBSTR bstr = emailData1.GetAttachmentData()[0].GetSourcePath().c_str();
    
    //CComVariant variant;
    CComVariant comVarOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); 
    
    g_pOutlookObj->get_App()->CreateItemFromTemplate(bstr, comVarOptional, &m_spNewMailItem);//pay attention to 2th, 3th parameter
    
    if( m_spNewMailItem == NULL) DP((L"test gewei create item failed!"));
    DP((L"test gewei create item success!"));
    
    //get email type, and just process some type of email.
    ITEM_TYPE emailType = DEFAULT;
    
    
    CComPtr<Outlook::_DistListItem> spOutlookItem = 0;
    
    //Distribution List Item, its outlook type is olDistributionListItem. It is a concept of Contact Group.
    HRESULT hr = m_spNewMailItem->QueryInterface(Outlook::IID__DistListItem, (void**)&spOutlookItem);
    if(SUCCEEDED(hr) && spOutlookItem)
    {
    
      // handle attachments
    
      CComPtr<Outlook::Attachments> spAttachments;
      hr = spOutlookItem->get_Attachments(&spAttachments);
      if(SUCCEEDED(hr))
      {
        long nAttchmentCount, nAttachIndex = 0;
        hr = spAttachments->get_Count((long*)&nAttchmentCount);
        if(SUCCEEDED(hr) && 0 < nAttchmentCount)
        {
          CComPtr<Outlook::Attachment> spAttachment = 0;
          for (long idxAttachment = 0; idxAttachment < nAttchmentCount; idxAttachment++)
          {
            VARIANT vi; vi.vt = VT_INT; vi.intVal = nAttachIndex+1;
            hr = spAttachments->Item(vi, &spAttachment);
            if(SUCCEEDED(hr) && NULL != spAttachment)
            {
              OlAttachmentType eAttachmentType;
              hr = spAttachment->get_Type(&eAttachmentType); //eAttachmentType = olByValue
              if(SUCCEEDED(hr) )
              {
                DLOG(L"Attachment_%d.eAttachmentType = %d", idxAttachment, (int)eAttachmentType);
              }
    
              long lAttachmentSize;
              hr = spAttachment->get_Size(&lAttachmentSize); //6405
              if(SUCCEEDED(hr) )
              {
                DLOG(L"Attachment_%d.Size = %d", idxAttachment, lAttachmentSize);
              }
    
              CComBSTR spbsPathName;
              hr = spAttachment->get_PathName(&spbsPathName); // hr = S_OK: NULL, spbsPathName = <Bad Ptr>
              if(SUCCEEDED(hr))
              {
                DLOG(L"Attachment_%d.PathName = %s", idxAttachment, (LPCWSTR)spbsPathName);
              }
    
              CComBSTR spbsTemporaryFilePath;
              hr = spAttachment->GetTemporaryFilePath(&spbsTemporaryFilePath); // hr = E_FAIL: NULL, spbsTemporaryFilePath = <Bad Ptr>
              if(SUCCEEDED(hr)){
                DLOG(L"Attachment_%d.TemporaryFilePath = %s", idxAttachment, (LPCWSTR)spbsTemporaryFilePath);
              }
            }
          }
        }
      }
    
    
      // handle contact members in contact group
      long lMemberCount = 0;
      hr = spOutlookItem->get_MemberCount(&lMemberCount);
      if(SUCCEEDED(hr) && lMemberCount)
      {
        CComPtr<Outlook::Recipient> spRecipient;
        
        // NOTE: The index starts with 1. See Outlook::Recipient.get_Index for details 
        for (long idxMember = 1; idxMember <= lMemberCount; idxMember++)
        {
          //Retrieve a Recipient object representing a member in a distribution list
          hr = spOutlookItem->GetMember(idxMember, &spRecipient);
          if(SUCCEEDED(hr) && NULL != spRecipient)
          {
            CComBSTR spbsAddress, spbsName;
            CComPtr<Outlook::_PropertyAccessor> spPropertyAccessor;
    
            hr = spRecipient->get_Address(&spbsAddress); //OK. e.g  Bard.Fang@ms.com
            if(SUCCEEDED(hr))
            {
              DLOG(L"Member_%d.Address = %s", idxMember, (LPCWSTR)spbsAddress);
            }
    
            hr = spRecipient->get_Name(&spbsName); //OK. e.g Bard (JiangHu) Fang
            if(SUCCEEDED(hr))
            {
              DLOG(L"Member_%d.Name = %s", idxMember, (LPCWSTR)spbsName);
            }
    
    
            hr = spRecipient->get_PropertyAccessor(&spPropertyAccessor);
            if(SUCCEEDED(hr))
            {
              CComVariant spvFullName;
              hr = spPropertyAccessor->GetProperty(CComBSTR(L"FullName"), &spvFullName);
              if(SUCCEEDED(hr))
              {
                DLOG(L"Member_%d.GetProperty@FullName = %s", idxMember, spvFullName.bstrVal);
              }
    
              //LPCWSTR PR_OFFICE_LOCATION_W = L"http://schemas.microsoft.com/mapi/proptag/0x3A19001F";
              LPCWSTR PR_SMTP_ADDRESS = L"http://schemas.microsoft.com/mapi/proptag/0x39FE001E";
    
              CComVariant spvJobTitle; //spvJobTitle = {"Bard.Fang@ms.com" VT_BSTR}
              hr = spPropertyAccessor->GetProperty(CComBSTR(PR_SMTP_ADDRESS), &spvJobTitle);
              if(SUCCEEDED(hr))
              {
                DLOG(L"Member_%d.GetProperty@PR_SMTP_ADDRESS = %s", idxMember, spvJobTitle.bstrVal);
              }
    
              wchar_t wszPropTag[256] = L"http://schemas.microsoft.com/mapi/proptag/", *pwszPropTagEnd = wszPropTag + wcslen(wszPropTag);
              //wstring wsPropTag = L"http://schemas.microsoft.com/mapi/proptag/";
              wsprintfW(pwszPropTagEnd, L"0x%X", PR_OFFICE_LOCATION_W);
    
              CComVariant spvOfficeLocation;
              hr = spPropertyAccessor->GetProperty(CComBSTR(wszPropTag), &spvOfficeLocation);
              if(SUCCEEDED(hr))
              {
                DLOG(L"Member_%d.GetProperty@PR_OFFICE_LOCATION_W = %s", idxMember, spvOfficeLocation.bstrVal);
              }
    
              printPropTag(spPropertyAccessor, PR_COMPANY_NAME_W);
            }
    
            CComPtr<Outlook::AddressEntry> spAddrEntry;
            hr = spRecipient->get_AddressEntry(&spAddrEntry);
    
            //VARIANT_BOOL varbool;
            //hr = spRecipient->Resolve(&varbool);
    
            if(SUCCEEDED(hr) && NULL != spAddrEntry)
            {
              CComPtr<Outlook::_ContactItem> spContactItem;
              hr = spAddrEntry->GetContact(&spContactItem); //with error:hr = 0x80040201 An event was unable to invoke any of the subscribers 
              if(SUCCEEDED(hr) && NULL != spContactItem)
              {
                CComBSTR spbsCompanyName;
                hr = spContactItem->get_CompanyName(&spbsCompanyName);
                if(SUCCEEDED(hr))
                {
                  DLOG(L"Member_%d.AddressEntry.Contact.CompanyName = %s", idxMember, (LPCWSTR)spbsCompanyName);
                }
              }
    
              CComPtr<Outlook::_ExchangeUser> spExchangeUser;
              hr = spAddrEntry->GetExchangeUser(&spExchangeUser); //hr = 0x80040201 An event was unable to invoke any of the subscribers 
              if(SUCCEEDED(hr) && NULL != spExchangeUser)
              {
                CComBSTR spbsCompanyName;
                hr = spExchangeUser->get_CompanyName(&spbsCompanyName);
                if(SUCCEEDED(hr))
                {
                  DLOG(L"Member_%d.AddressEntry.ExchangeUser.CompanyName = %s", idxMember, (LPCWSTR)spbsCompanyName);
                }
              }
            }
          }
        }
      }
    
    }
    
    

    Hi Dmitry,


    Above is my testing code, I try my best to do as you have suggested.

    But still, we just cant get :

    spRecipient->get_Address(&spbsAddress); //OK. e.g  Bard.Fang@ms.com

    spRecipient->get_Name(&spbsName); //OK. e.g Bard (JiangHu) Fang


    and failed to get contact item:

    hr = spAddrEntry->GetContact(&spContactItem); //with error:hr = 0x80040201 An event was unable to invoke any of the subscribers


    We have tryed other possible ways, but still failed.

    Dmitry, if you have some suggestions, please tell us, we need your helo!

    Thank you!


    Leo

    Thursday, December 29, 2016 3:34 AM
  • The error is MAPI_E_UNKNOWN_ENTRYID, which means the address entry does nto come from one of the IPM.Contact items, or that the contact does not exist - this would make sense if the DL comes from another computer.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, December 29, 2016 5:44 AM
  • Dear Dmitry,

    Firstly, we use the contact group that created outlook(new item->contact group) for testing, so the .msg file should be right.

    secondly, do you mean, we get address entry wrong? Pleas review the getting address entry progress.

    Thank you very much!

    Leo

    Thursday, December 29, 2016 10:21 AM
  • If the members of the distribution list do not exist as individual contacts in Outlook's Contacts folder then you will not be able to obtain the contact information for the distlist members.  The contact information is not saved in the DistListtem. 

    Outlook resolves the members of a DistListItem against the Contacts Folder in order to obtain member details.  Even after you retrieve an AddressEntry item for the Recipient contained in the DistListItem, the call to GetContact fails because the ContactItem does not exist.

    Thursday, December 29, 2016 10:27 AM
  • Thank you for your help. We have do as you told ablove. But the error informaiton is still the same.

    Maybe I don't really know what is individual contact. My testing contact group and contct are just as below:

    Contact group2 contains the other contact that are in Outlool's Contacts folder(I think they are individual).

    I have shown the testing code in ablove.

    Friend, pls help us to check the code and find some information to slove the problem.

    Thank you very much!

    Leo

    Tuesday, January 3, 2017 7:28 AM
  • Hi LeoGe,

    Do you parse contact group in the sender side or receiver side? To avoid the contact not exist in receiver side, I suggest you make a test with your code in sender side to check whether this error still exist.

    In addition, to check whether it is related with contact group, I suggest you make a test with GetContact on a single contact item.

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, January 5, 2017 5:15 AM