.msg 檔是什麼?格式解析

從技術角度解析 Outlook 的 .msg 格式:OLE2 容器、MAPI 屬性資料流、內文的儲存方式,以及為什麼其他軟體讀不了它。

.msg 是 Microsoft Outlook 用來把單一項目存成獨立檔案的格式。雖然名字 叫 msg,它裝的不只是郵件 —— 從 Outlook 存出的約會、聯絡人、工作、記事與會議邀請, 產生的都是 .msg 檔。

外層容器:Compound File Binary Format

.msg 本質上是一個 OLE2 複合文件 —— 等於在單一檔案 裡塞了一套小型檔案系統,有目錄(storage)也有檔案(stream)。這類檔案開頭一定 是同樣的八個簽章位元組 D0 CF 11 E0 A1 B1 1A E1,因此就算副檔名被改過, 解析器依然認得出來。

舊版的 .doc.xls.ppt 用的是同一種容器, 差別在於內部資料流的命名與意義 —— .msg 的部分由 [MS-OXMSG] 規格定義。

裡面存了什麼

每個郵件屬性各自存成一個資料流,名稱就是 MAPI 屬性標籤(16 位元屬性編號 + 16 位元 型別)。例如:

屬性標籤內容
PidTagSubject0037001F主旨
PidTagBody1000001F純文字內文
PidTagHtml10130102HTML 內文(原始位元組)
PidTagRtfCompressed10090102壓縮過的 RTF 內文
PidTagSenderEmailAddress0C1F001F寄件者位址

收件者與附件則不是屬性,而是子儲存區 —— 例如 __recip_version1.0_#00000000 __attach_version1.0_#00000000 —— 各自內部再放自己的屬性資料流。

內文的三種存法

這正是多數簡易檢視器出錯的地方,也是同一個檔案在某個工具裡完美、在另一個工具裡 卻空白的原因。Outlook 可能把內文存成:

  • 純文字,放在 PidTagBody
  • HTML,放在 PidTagHtml,是必須依 PidTagInternetCodepage 指定的字碼頁去解碼的原始位元組。 一律當成 UTF-8 解碼,正是中文、日文、韓文、西里爾文與希臘文郵件變成亂碼的主因。
  • 壓縮 RTF,放在 PidTagRtfCompressed。當原始郵件 是 HTML 時,Outlook 會依 [MS-OXRTFEX] 規格把 HTML 封裝進 RTF 裡。要還原就得先解壓縮,再處理 \htmltag\htmlrtf 控制字進行反封裝。跳過這一步的檢視器,在相當比例的真實 Outlook 郵件上都會顯示 空白內文。

內嵌圖片與 cid: 參照

出現在內文中的圖片,其實是帶有 PidTagAttachContentId 的一般附件, HTML 內文再以 <img src="cid:image001.png@01D9…"> 參照它們。 檢視器必須把每個 cid: 對應回附件並換成可用的網址,否則簽名檔與 公司 logo 的位置就只會剩下破圖圖示。

為什麼其他軟體不支援

微軟雖然公開了規格,卻從未把它推為交換標準;而且格式中編入了大量 Exchange 專屬 概念 —— legacy DN、投票按鈕、委派資訊、訊息類別 —— 在標準網際網路郵件中根本沒有 對應物。要支援它就等於實作一份微軟規格,對競爭者自家格式毫無好處,所以幾乎沒人做。

標準的替代方案是純文字的 .eml。可以 比較兩種格式,看看轉檔會得到什麼、失去什麼。

現在就開啟一個 .msg 檔

不需註冊、不需上傳、不需安裝任何軟體。

開啟檢視器