2015年7月31日金曜日

Outlook 2010 アドイン開発で Outlook の問題を発見。

Outlook のメール形式に「リッチテキスト形式」ってのがあって、アドインで添付すると添付ファイルが表示されなかったりする問題もあるんだけど、もっと致命的なバグを見つけてしまった。

再現性の確認のために手順書いておきます。

環境:Windows 8.1 Pro 64bit + Outlook 2010 + VisualStudio 2012 Pro

手順:
1.C:\Temp\texst1.txt ファイルを用意

2.Outlook2010 アドインプロジェクトを作成
  2-1.アドインを作成
  2-2.インスペクタを登録
  2-3.BeforeAttachAdd() を記述
  2-4.メッセージボックスを表示
        [キャンセル]=添付を削除
        [いいえ]=そのまま添付
        [はい]=ファイル交換処理
  2-5.ファイルを交換(「はい」の場合)
        int index = attachment.Index
        (Parent).Attachments.Remove(index);
        (Parent).Attachments.Add("c:\Temp\test1.txt");を実施

3.Outlookを実行(デバッグ実行で)
  3-1.新規メールを作成
  3-2.リッチテキスト形式に変更
  3-3.ファイルを添付
  3-4-1-1.添付ファイルを [CTRL]-[C]でコピー
  3-4-1-2.[CTRL]-[V]で貼り付け
  または
  3-4-2-1.添付ファイルドラッグして別の位置に移動

  Outlook が落ちる。

HTML形式、テキスト形式のメールでは落ちません。
ま、再現性確認のためにメッセージボックスはいらないんだけどね。

以下、ソースの 抜粋です。(コメントなくてすんません。)

    public partial class ThisAddIn
    {
        Outlook.Inspectors Inspectors;

        private const string TempFile = @"C:\Temp\test1.txt";

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            Inspectors = Application.Inspectors;
            Inspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);
        }

        private void Inspectors_NewInspector(Outlook.Inspector inspector)
        {
            if (inspector.CurrentItem == null)
            {
                return;
            }

            Outlook.MailItem mailItem = inspector.CurrentItem as Outlook.MailItem;
            if (mailItem != null)
            {
                // add event handler for BeforeAttachAdd
                Outlook.ItemEvents_10_BeforeAttachmentAddEventHandler beforeAddHandler = new Outlook.ItemEvents_10_BeforeAttachmentAddEventHandler(OnBeforeAttachmentAdd);
                mailItem.BeforeAttachmentAdd += beforeAddHandler;
                return;
            }
        }

        private void OnBeforeAttachmentAdd(Outlook.Attachment Attachment, ref bool Cancel)
        {
            // change file
            int index = Attachment.Index;
            Outlook.MailItem mailItem = Attachment.Parent as Outlook.MailItem;
            if(mailItem != null){
                Outlook.Attachments attachments = mailItem.Attachments;
                attachments.Remove(index);

                attachments.Add(TempFile, Outlook.OlAttachmentType.olByValue);
            }
            return;
        }

    }

特定するまで、結構時間かかっちゃうんだよね。
こういう問題を発見するのって、開発しているアドイン側の問題として指摘されるわけで、クライアントさんからものすごい指摘を受けながら対策しなきゃならないんで、プレッシャーもかかるし調査にもとっても時間がかかって進捗とかほかの作業にも影響が出ます。


なんか、損な役割だなぁって思っちゃうです。

上記の件はマイクロソフトさんに報告済みですので、将来的にこの記事は意味を持たなくなります。

あと、このコードを参考にして自分のアドインを開発しようとする方がいるかもしれませんので、サンプルコードで端折っていることを書いておきます。

・インスペクタで += したハンドラは、クローズ時に -= で解除します。(ラッパクラスを作るといい)
・左辺値に代入したCOMオブジェクトは、Marshal.ReleaseComObject で参照解除します。

0 件のコメント:

コメントを投稿