Discussion:
How to access message recipients (MAPI)
(too old to reply)
Ivan
2007-06-26 05:15:02 UTC
Permalink
I use next code (was simplified here) for accessing message recipients, but
it works too slowly:

SizedSPropTagArray( 3, cols ) = { 3, { PR_ENTRYID, PR_SUBJECT,
PR_SENDER_NAME } };
MAPIUtils::QueryAllRows( spTable, (SPropTagArray*)&cols, 0, 0, 0, &pRowSet );
for( UINT i = 0; i < pRowSet->cRows; i++ )
{
// processing recipients
spFolder->OpenEntry( row->lpProps[0].Value.bin.cb,
(LPENTRYID)row->lpProps[0].Value.bin.lpb, NULL, 0, &messagetype,
(IUnknown**)&spMessage );
CComPtr<IMAPITable> spRecipientTable;
spMessage->GetRecipientTable( MAPI_UNICODE, &spRecipientTable );
SizedSPropTagArray( 3, rcptcols ) = { 3, { PR_EMAIL_ADDRESS,
PR_RECIPIENT_TYPE, PR_DISPLAY_NAME } };
MAPIUtils::QueryAllRows( spRecipientTable, (SPropTagArray*)&rcptcols, 0,
0, 0, &pRows );
for( UINT r = 0; r < pRows->cRows; r++ )
{
// loop through all the recipient' properties
for ( int ii = 0; ii < pRows->aRow[r].cValues; ii++ )
{
ULONG ulPT = pRows->aRow[r].lpProps[ii].ulPropTag;
switch ( ulPT )
{
case PR_EMAIL_ADDRESS:
// ...
}
}
}

//processing PR_SUBJECT and PR_SENDER_NAME properties here...
}

Are there another ways to read message recipients without opening entry and
retrieving recipients table?
Dmitry Streblechenko
2007-06-26 23:18:08 UTC
Permalink
No, I am afraid not. You can create a restriction on the on the recipients
though.
Do you really need to process all recipients in all messages in a given
folder?

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Post by Ivan
I use next code (was simplified here) for accessing message recipients, but
SizedSPropTagArray( 3, cols ) = { 3, { PR_ENTRYID, PR_SUBJECT,
PR_SENDER_NAME } };
MAPIUtils::QueryAllRows( spTable, (SPropTagArray*)&cols, 0, 0, 0, &pRowSet );
for( UINT i = 0; i < pRowSet->cRows; i++ )
{
// processing recipients
spFolder->OpenEntry( row->lpProps[0].Value.bin.cb,
(LPENTRYID)row->lpProps[0].Value.bin.lpb, NULL, 0, &messagetype,
(IUnknown**)&spMessage );
CComPtr<IMAPITable> spRecipientTable;
spMessage->GetRecipientTable( MAPI_UNICODE, &spRecipientTable );
SizedSPropTagArray( 3, rcptcols ) = { 3, { PR_EMAIL_ADDRESS,
PR_RECIPIENT_TYPE, PR_DISPLAY_NAME } };
MAPIUtils::QueryAllRows( spRecipientTable, (SPropTagArray*)&rcptcols, 0,
0, 0, &pRows );
for( UINT r = 0; r < pRows->cRows; r++ )
{
// loop through all the recipient' properties
for ( int ii = 0; ii < pRows->aRow[r].cValues; ii++ )
{
ULONG ulPT = pRows->aRow[r].lpProps[ii].ulPropTag;
switch ( ulPT )
{
// ...
}
}
}
//processing PR_SUBJECT and PR_SENDER_NAME properties here...
}
Are there another ways to read message recipients without opening entry and
retrieving recipients table?
Ivan
2007-06-27 03:52:01 UTC
Permalink
I need to get all recipients (their names and emails) of every message.
Message properties PR_DISPLAY_TO and PR_DISPLAY_CC are not exactly what I
need.
Dmitry Streblechenko
2007-06-27 06:54:29 UTC
Permalink
Then opening each and every message is your only option...

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Post by Ivan
I need to get all recipients (their names and emails) of every message.
Message properties PR_DISPLAY_TO and PR_DISPLAY_CC are not exactly what I
need.
Ivan
2007-06-27 08:46:00 UTC
Permalink
Ok. Thanks.
Ivan
2007-07-10 12:26:04 UTC
Permalink
Dmitry, is it possible to open each message avoiding of calling
OpenEntry(msgEntryID)? It takes high time.

Now I open mapi folder using spIMsgStore->OpenEntry(), then open mapi table
- spIFolder->GetContentsTable(), query all rows from the table (also using
SetColumns() to access only one property - PR_ENTRYID), and after that I
should open each message using spFolder->OpenEntry() to have an ability to
call GetRecipientTable() method.

What if I need to read only all recipients for each message without reading
other message properties?

In MSDN I found that contents of PR_MESSAGE_RECIPIENTS should be accessed by
the IMAPIProp::OpenProperty method, requesting the IID_IMAPITable interface
identifier. But I have no idea how to realize it.

The fact is that Reunion's Outlook Addin (www.reunion.com) read all
recipients from all messages extremely fast (only first launch is meaningful
cause it cashes results in its own db).
Dmitry Streblechenko
2007-07-10 17:00:36 UTC
Permalink
No, no way around it. You either call IMessage::GetRecipientTable or
IMessage::OpenProperty(PR_MESSAGE_RECIPIENTS).

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Post by Ivan
Dmitry, is it possible to open each message avoiding of calling
OpenEntry(msgEntryID)? It takes high time.
Now I open mapi folder using spIMsgStore->OpenEntry(), then open mapi table
- spIFolder->GetContentsTable(), query all rows from the table (also using
SetColumns() to access only one property - PR_ENTRYID), and after that I
should open each message using spFolder->OpenEntry() to have an ability to
call GetRecipientTable() method.
What if I need to read only all recipients for each message without reading
other message properties?
In MSDN I found that contents of PR_MESSAGE_RECIPIENTS should be accessed by
the IMAPIProp::OpenProperty method, requesting the IID_IMAPITable interface
identifier. But I have no idea how to realize it.
The fact is that Reunion's Outlook Addin (www.reunion.com) read all
recipients from all messages extremely fast (only first launch is meaningful
cause it cashes results in its own db).
Ivan Copernic
2010-11-16 01:16:01 UTC
Permalink
Hello,

Yes ! Use DCI Mail Processor SDK EMAPI wrapper to do this.

OpenMailbox(Your PST file name)

GetFolderCount - to get folders count

GetMessageProp - to get all mail message properties

Just 3 simple API call

Google - "DCI Mail Processor"
Post by Ivan
I use next code (was simplified here) for accessing message recipients, but
SizedSPropTagArray( 3, cols ) = { 3, { PR_ENTRYID, PR_SUBJECT,
PR_SENDER_NAME } };
MAPIUtils::QueryAllRows( spTable, (SPropTagArray*)&cols, 0, 0, 0, &pRowSet );
for( UINT i = 0; i < pRowSet->cRows; i++ )
{
// processing recipients
spFolder->OpenEntry( row->lpProps[0].Value.bin.cb,
(LPENTRYID)row->lpProps[0].Value.bin.lpb, NULL, 0, &messagetype,
(IUnknown**)&spMessage );
CComPtr<IMAPITable> spRecipientTable;
spMessage->GetRecipientTable( MAPI_UNICODE, &spRecipientTable );
SizedSPropTagArray( 3, rcptcols ) = { 3, { PR_EMAIL_ADDRESS,
PR_RECIPIENT_TYPE, PR_DISPLAY_NAME } };
MAPIUtils::QueryAllRows( spRecipientTable, (SPropTagArray*)&rcptcols, 0,
0, 0, &pRows );
for( UINT r = 0; r < pRows->cRows; r++ )
{
// loop through all the recipient' properties
for ( int ii = 0; ii < pRows->aRow[r].cValues; ii++ )
{
ULONG ulPT = pRows->aRow[r].lpProps[ii].ulPropTag;
switch ( ulPT )
{
// ...
}
}
}
//processing PR_SUBJECT and PR_SENDER_NAME properties here...
}
Are there another ways to read message recipients without opening entry and
retrieving recipients table?
Post by Dmitry Streblechenko
No, I am afraid not. You can create a restriction on the on the recipients
though.
Do you really need to process all recipients in all messages in a given
folder?
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Post by Ivan
I need to get all recipients (their names and emails) of every message.
Message properties PR_DISPLAY_TO and PR_DISPLAY_CC are not exactly what I
need.
Post by Dmitry Streblechenko
Then opening each and every message is your only option...
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Post by Ivan
Ok. Thanks.
Post by Ivan
Dmitry, is it possible to open each message avoiding of calling
OpenEntry(msgEntryID)? It takes high time.
Now I open mapi folder using spIMsgStore->OpenEntry(), then open mapi table
- spIFolder->GetContentsTable(), query all rows from the table (also using
SetColumns() to access only one property - PR_ENTRYID), and after that I
should open each message using spFolder->OpenEntry() to have an ability to
call GetRecipientTable() method.
What if I need to read only all recipients for each message without reading
other message properties?
In MSDN I found that contents of PR_MESSAGE_RECIPIENTS should be accessed by
the IMAPIProp::OpenProperty method, requesting the IID_IMAPITable interface
identifier. But I have no idea how to realize it.
The fact is that Reunion's Outlook Addin (www.reunion.com) read all
recipients from all messages extremely fast (only first launch is meaningful
cause it cashes results in its own db).
Post by Dmitry Streblechenko
No, no way around it. You either call IMessage::GetRecipientTable or
IMessage::OpenProperty(PR_MESSAGE_RECIPIENTS).
Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy - Outlook, CDO
and MAPI Developer Tool
Submitted via EggHeadCafe
Microsoft .NET DataBase Access For Beginners
http://www.eggheadcafe.com/training-topic-area/Microsoft-NET-DataBase-Access/1/SQL-Server-Oracle-DB2-Informix-Query-Samples.aspx
Loading...