HOWTO: Save a Message Attachment to File (173353)
The information in this article applies to:
- Microsoft Extended Messaging Application Programming Interface (MAPI)
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:
- Open the Attachments table, including the following columns:
PR_ATTACH_FILENAME and PR_ATTACH_NUM.
- Open an attachment in the Attachments table.
- Create a file for the attachment.
- 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 <initguid.h>
#include <mapiutil.h>
*/
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:
Modification Type: | Minor | Last Reviewed: | 8/18/2005 |
---|
Keywords: | kbhowto kbMsg KB173353 |
---|
|