ข้อมูล: บันทึกข้อความไปยังไฟล์ผสมผงชูรส


สรุป


บทความนี้ประกอบด้วยโค้ดที่อธิบายวิธีการบันทึกข้อความลงในเอกสารประกอบ--เฉพาะไฟล์ msg--ที่สามารถอ่านได้โดยไคลเอ็นต์ที่สนับสนุนรูปแบบไฟล์ msg

ข้อมูลเพิ่มเติม


ฟังก์ชันด้านล่างจะใช้วัตถุข้อความที่ถูกต้องเป็นพารามิเตอร์ในพารามิเตอร์และใช้คุณสมบัติของการสร้างข้อความที่ซ้ำกันและบันทึกไปยังไฟล์ผสมโดยใช้รูปแบบ msg บรรทัดชื่อเรื่องของข้อความจะถูกใช้เป็นชื่อไฟล์ของไฟล์ใหม่ หมายเหตุ: อักขระพิเศษในบรรทัดชื่อเรื่องของพารามิเตอร์ในพารามิเตอร์ของฟังก์ชันนี้อาจทำให้เกิดผลลัพธ์ที่ไม่คาดคิด ในขณะที่โค้ดสามารถเขียนเพื่อหลีกเลี่ยงอักขระพิเศษในบรรทัดชื่อเรื่องได้ไม่ germane ไปยังหัวข้อและโค้ดดังกล่าวจะถูกปล่อยออกมา
#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 นี่คือเนื่องจากปัญหาที่ทราบแล้วเกี่ยวกับการจัดเก็บและสตรีมที่มีโครงสร้าง ทุกครั้งที่มีการเพิ่มสิ่งที่แนบมาหรือผู้รับใหม่ในข้อความที่ถูกบันทึกไว้ในที่เก็บข้อมูลที่มีโครงสร้างไฟล์ที่เก็บรากใหม่จะเปิดขึ้น ไฟล์เหล่านี้จะไม่ถูกปิดจนกว่าจะเสร็จสิ้นการทำธุรกรรม เนื่องจากระบบปฏิบัติการกำหนดจำกัดจำนวนไฟล์ที่เก็บรากที่พร้อมกันจะไม่มีวิธีแก้ไขปัญหาชั่วคราวที่ทราบ สำหรับข้อมูลเพิ่มเติมให้คลิกหมายเลขบทความด้านล่างนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:
๑๖๓๒๐๒ ขีดจำกัดของจำนวนไฟล์ที่เก็บรากของ Simultaeously ที่เปิดอยู่
Outlook เวอร์ชันทั้งหมดจะได้รับผลกระทบจากข้อจำกัดนี้ด้วย