読者です 読者をやめる 読者になる 読者になる

【VSTO】Outlookで添付されたファイルを強制的にZIPに圧縮する

添付ファイルツールでは、任意に圧縮を行い添付します。
あくまでも、ユーザーが添付ファイルツールで"圧縮して添付"を行ったときのみ。

そうではなく、無条件に圧縮し添付することもできます。

「ドコで使うの?!」
「なんか困った時!」

実装

添付を行った瞬間に圧縮して添付を行う事ができます。
手っ取り早くリボン(ビジュアルデザイナ)で作成しました。

お約束のRibbonTypeは、メッセージ編集画面なので"Microsoft.Outlook.Mail.Compose"を選択しておきます。

ZIPファイルを作成するために、DotNetZipをNugetから追加していますのでお忘れなく追加してください。

using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Interop.Outlook;
using System.IO;
using Ionic.Zip;
using Ionic.Zlib;

public partial class Ribbon1
{
  Outlook.MailItem mailItem = null;
  private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
  {
    //メールオブジェクト取得
    if (mailItem == null)
    {
      var inspector = base.Context as Microsoft.Office.Interop.Outlook.Inspector;
      mailItem = inspector.CurrentItem as Outlook.MailItem;
      //ファイルが添付された時のイベントを登録
      (mailItem as ItemEvents_10_Event).BeforeAttachmentAdd += Ribbon1_BeforeAttachmentAdd;
    }
  }
  void Ribbon1_BeforeAttachmentAdd(Attachment attachment, ref bool Cancel)
  {
    //オリジナル添付ファイル
    var originalFile = attachment.GetTemporaryFilePath();
    //圧縮後添付ファイル
    var compressFile = attachment.GetTemporaryFilePath() + ".zip";
    //表示ファイル名
    var displayName = attachment.DisplayName;
    //オリジナルの添付ファイルを削除
    attachment.Delete();

    using (ZipFile zip = new ZipFile(Encoding.GetEncoding("Shift_JIS")))
    {
      zip.CompressionLevel = CompressionLevel.BestCompression;
      zip.AddFiles(new string[] { originalFile }, false, "");

      zip.Save(compressFile);
    }
    //ZIPに圧縮したファイルを再添付する
    mailItem.Attachments.Add(compressFile, DisplayName: displayName);
  }
}

メッセージ編集画面でファイルが添付されると必ず”BeforeAttachmentAdd”のイベントが呼び出されます。
イベントコールバックの中で、ユーザーによって添付されたオリジナルのファイルを削除したあとに、オリジナルをZIPに圧縮したファイルを再添付しているだけです。

初めて知ったのですが、再添付をした時には、BeforeAttachmentAddのイベントが呼び出されないんですよね。不思議。
作ってて思いついたのが、メッセージ編集画面でファイルが添付された都度、圧縮するんじゃなくて、送信ボタンを押した時に一括で圧縮したほうがいいかもしれません。