Microsoft KB Archive/173353

= HOWTO: Save a Message Attachment to File =

Article ID: 173353

Article Last Modified on 8/18/2005

-

APPLIES TO


 * Microsoft Messaging Application Programming Interface

-



This article was previously published under Q173353



SUMMARY
The following code example demonstrates how to open an attachment and copy the contents to a file in the current directory.



MORE INFORMATION
Use the following steps to open an attachment and copy the contents to a file in the current directory:


 * 1) Open the Attachments table, including the following columns:

PR_ATTACH_FILENAME and PR_ATTACH_NUM.
 * 1) Open an attachment in the Attachments table.
 * 2) Create a file for the attachment.
 * 3) Copy the contents of the attachment to the newly created file.

Sample Code
/* This code assumes that you already have an IMessage object, pointed to by the variable pMsg. This IMessage object should have been opened with the MAPI_MODIFY flag.

This code also assumes that PR_ATTACH_METHOD equals ATTACH_BY_VALUE. See the note that follows this sample code for more information. */

/* You should have the following define and include lines for this code to compile and link correctly:

#define USES_IID_IMAPITable #define INITGUID

#include          #include    */

HRESULT WriteAttachToFile ( LPMESSAGE pMsg ) {     SizedSPropTagArray(1,g_sptMsgProps) = {1, PR_HASATTACH};

LPSPropValue pProps = NULL; HRESULT hRes = 0; ULONG cVals = 0;

if (FAILED(hRes = pMsg->GetProps((LPSPropTagArray) &g_sptMsgProps,                                      0,                                       &cVals,                                       &pProps))) goto Quit; else hRes = S_OK;

if (PR_HASATTACH == pProps[0].ulPropTag && pProps[0].Value.b)     { LPMAPITABLE pAttTbl = NULL; LPSRowSet pRows = NULL; static SizedSPropTagArray(2,sptCols) = {2,PR_ATTACH_LONG_FILENAME, PR_ATTACH_NUM};

if (SUCCEEDED(hRes = pMsg -> OpenProperty(PR_MESSAGE_ATTACHMENTS,                                                 &IID_IMAPITable,                                                  0,                                                  0,                                                  (LPUNKNOWN *) &pAttTbl))) {

if (SUCCEEDED(hRes = pAttTbl -> SetColumns(                                             (LPSPropTagArray) &sptCols,                                              TBL_BATCH))) {

if (SUCCEEDED(hRes = HrQueryAllRows(pAttTbl,                                             (LPSPropTagArray) &sptCols,                                              NULL,                                              NULL,                                              0,                                              &pRows))) {

for (ULONG i = 0; i < pRows -> cRows; i++) {               LPATTACH lpAttach = NULL;

// Verify we received a filename from GetProps if (! PR_ATTACH_FILENAME ==                     pRows->aRow[i].lpProps[0].ulPropTag) break;

// Verify we received an Attachment Index from GetProps if (! PR_ATTACH_NUM == pRows->aRow[i].lpProps[1].ulPropTag) break;

// Open the attachment if (SUCCEEDED(hRes = pMsg->OpenAttach (                                 pRows->aRow[i].lpProps[1].Value.l,                                  NULL, MAPI_BEST_ACCESS, &lpAttach))) {                 LPSTREAM pStrmSrc = NULL, pStrmDest = NULL; STATSTG StatInfo;

// Open the property of the attachment // containing the file data if (FAILED(hRes = lpAttach->OpenProperty(                                                PR_ATTACH_DATA_BIN,                                                 (LPIID)&IID_IStream,                                                 0,                                                 MAPI_MODIFY,                                                 (LPUNKNOWN *)&pStrmSrc))) break;

// Open an IStream interface and create the file at the // same time. This code will create the file in the // current directory. if (FAILED(hRes = OpenStreamOnFile(                                    MAPIAllocateBuffer,                                     MAPIFreeBuffer,                                     STGM_CREATE | STGM_READWRITE,                                     pRows->aRow[i].lpProps[0].Value.lpszA,                                     NULL,                                     &pStrmDest))) break;

pStrmSrc -> Stat(&StatInfo, STATFLAG_NONAME);

hRes = pStrmSrc -> CopyTo(pStrmDest,                                            StatInfo.cbSize,                                             NULL,                                             NULL);

// Commit changes to new stream pStrmDest -> Commit(0);

// Release each of our streams pStrmDest -> Release; pStrmSrc -> Release;

}

// Release the attachment lpAttach -> Release; }           }          }        }

FreeProws(pRows);

if (pAttTbl) pAttTbl -> Release; }   Quit: MAPIFreeBuffer((LPVOID) pProps); return hRes; } NOTE: If the attachment is a message or structured storage (OLE object), there is no PR_ATTACH_DATA_BIN property. Another attachment property, PR_ATTACH_METHOD, essentially can contain four different values that tell you what to do:
 * ATTACH_BY_VALUE means that you work with the PR_ATTACH_DATA_BIN property.
 * ATTACH_BY_REFERENCE means that you work with PR_ATTACH_PATHNAME; the file is not physically included.
 * ATTACH_EMBEDDED_MESSAGE or ATTACH_OLE mean you call OpenProperty on PR_ATTACH_DATA_OBJ, which gives you back an IMessage or IStorage interface respectively.

For more information on the PR_ATTACH_METHOD property, see the following Microsoft Developer Network (MSDN) Web site:

http://msdn.microsoft.com/library/psdk/mapi/_mapi1book_pr_attach_method.htm

Keywords: kbhowto kbmsg KB173353

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.