INFO:將訊息儲存至 MSG 複合檔案

摘要

本文包含的程式代碼示範如何將訊息儲存至複合檔,特別是支援.msg檔格式的任何用戶端可讀取的.msg檔案。

其他相關資訊

下列函式會在 參數中使用有效的訊息物件做為 ,並使用其屬性來建立訊息的復本,並使用.msg格式將它儲存至複合檔。 訊息的主旨行會做為新檔案的檔名。

注意事項

此函式中 in 參數之 主旨行中的特殊字元可能會導致非預期的結果。 雖然程式代碼可以撰寫以避免主旨行中的特殊字元,但它不會與主題產生關聯,而且會刻意排除這類程序代碼。

#define INITGUID
#include <objbase.h>

#define USES_IID_IMessage

#include <mapix.h>
#include <mapitags.h>
#include <mapidefs.h>
#include <mapiutil.h>
#include <mapiguid.h>
#include <imessage.h>

// {00020D0B-0000-0000-C000-000000000046}
DEFINE_GUID(CLSID_MailMessage,
0x00020D0B,
0x0000, 0x0000, 0xC0, 0x00, 0x0, 0x00, 0x0, 0x00, 0x00, 0x46);

HRESULT SaveToMSG ( LPMESSAGE pMessage )
{
 HRESULT hRes = S_OK;
 LPSPropValue pSubject = NULL;
 LPSTORAGE pStorage = NULL;
 LPMSGSESS pMsgSession = NULL;
 LPMESSAGE pIMsg = NULL;
 SizedSPropTagArray ( 7, excludeTags );
 char szPath[_MAX_PATH];
 char strAttachmentFile[_MAX_PATH];
 LPWSTR lpWideCharStr = NULL;
 ULONG cbStrSize = 0L;

// create the file name in the directory where "TMP" is defined
 // with subject as the filename and ".msg" extension.

// get temp file directory
 GetTempPath(_MAX_PATH, szPath);

// get subject line of message to copy. This will be used as the
 // new file name.
 HrGetOneProp( pMessage, PR_SUBJECT, &pSubject );

// fuse path, subject, and suffix into one string
 strcpy ( strAttachmentFile, szPath );
 strcat ( strAttachmentFile, pSubject->Value.lpszA );
 strcat ( strAttachmentFile, ".msg");

// get memory allocation function
 LPMALLOC pMalloc = MAPIGetDefaultMalloc();

// Convert new file name to WideChar
 cbStrSize = MultiByteToWideChar (CP_ACP,
 MB_PRECOMPOSED,
 strAttachmentFile,
 -1, lpWideCharStr, 0);

MAPIAllocateBuffer ( cbStrSize * sizeof(WCHAR),
 (LPVOID *)&lpWideCharStr );

MultiByteToWideChar (CP_ACP,
 MB_PRECOMPOSED,
 strAttachmentFile,
 -1, lpWideCharStr, cbStrSize );

// create compound file
 hRes = ::StgCreateDocfile(lpWideCharStr,
 STGM_READWRITE |
 STGM_TRANSACTED |
 STGM_CREATE, 0, &pStorage);

// Open an IMessage session.
 hRes = ::OpenIMsgSession(pMalloc, 0, &pMsgSession);

// Open an IMessage interface on an IStorage object
 hRes = ::OpenIMsgOnIStg(pMsgSession,
 MAPIAllocateBuffer,
 MAPIAllocateMore,
 MAPIFreeBuffer,
 pMalloc,
 NULL,
 pStorage,
 NULL, 0, 0, &pIMsg);

// write the CLSID to the IStorage instance - pStorage. This will
 // only work with clients that support this compound document type
 // as the storage medium. If the client does not support
 // CLSID_MailMessage as the compound document, you will have to use
 // the CLSID that it does support.
 hRes = WriteClassStg(pStorage, CLSID_MailMessage );

// Specify properties to exclude in the copy operation. These are
 // the properties that Exchange excludes to save bits and time.
 // Should not be necessary to exclude these, but speeds the process
 // when a lot of messages are being copied.
 excludeTags.cValues = 7;
 excludeTags.aulPropTag[0] = PR_ACCESS;
 excludeTags.aulPropTag[1] = PR_BODY;
 excludeTags.aulPropTag[2] = PR_RTF_SYNC_BODY_COUNT;
 excludeTags.aulPropTag[3] = PR_RTF_SYNC_BODY_CRC;
 excludeTags.aulPropTag[4] = PR_RTF_SYNC_BODY_TAG;
 excludeTags.aulPropTag[5] = PR_RTF_SYNC_PREFIX_COUNT;
 excludeTags.aulPropTag[6] = PR_RTF_SYNC_TRAILING_COUNT;

// copy message properties to IMessage object opened on top of
 // IStorage.
 hRes = pMessage->CopyTo(0, NULL,
 (LPSPropTagArray)&excludeTags,
 NULL, NULL,
 (LPIID)&IID_IMessage,
 pIMsg, 0, NULL );

// save changes to IMessage object.
 pIMsg -> SaveChanges ( KEEP_OPEN_READWRITE );

// save changes in storage of new doc file
 hRes = pStorage -> Commit(STGC_DEFAULT);

// free objects and clean up memory
 MAPIFreeBuffer ( lpWideCharStr );
 pStorage->Release();
 pIMsg->Release();
 CloseIMsgSession ( pMsgSession );

pStorage = NULL;
 pIMsg = NULL;
 pMsgSession = NULL;
 lpWideCharStr = NULL;

return hRes;
}

所有版本的 Outlook 和 Exchange 用戶端支援CLSID_MailMessage作為複合檔。 使用不同 CLSID 的唯一原因是,當您將訊息寫入結構化記憶體時,支援使用不同 CLISD 的其他用戶端。

儲存具有大量收件者或附件的郵件時,CopyTo 作業可能會因為MAPI_E_NOT_ENOUGH_MEMORY而失敗。 這是因為結構化記憶體和數據流的已知問題。 每次將新的附件或收件者新增至儲存在結構化記憶體中的訊息時,就會開啟新的根記憶體檔案。 在交易完成之前,不會關閉這些檔案。 由於操作系統會限制同時開啟的根記憶體檔案數目,因此沒有已知的因應措施。