追記:やっぱり問題が発生するようです。エントリ内の写真が消えたりする問題が起きるようなので、この方法も駄目でした…orz

ひとつ前のエントリ(中まで知ろう!Windows Live Writer)で、Windows Live Writerの、SDKには載っていないクラスを色々と紹介しました。その内容をうけて、このエントリではPublish Notification Hook プラグインで、投稿前に記事内容を書き換える方法を紹介したいと思います。以前にも、SharpLab. – publish notification hooksでpost内容を書き換えるにはというエントリでpublish notification hooksプラグインで投稿内容を書き換える方法を紹介したことがありました。ですが、

WLW 自体は書き換えられることを想定してないので、プラグインから書き換えても投稿後にエディタ中の表示は変化しません。

Publish Notification Hook プラグイン 値の書き換え-katamari.wankuma.com

というJZ5さんの検証エントリの通り、投稿後の画面がおかしくなる問題がありました。今回の方法ではその回避を図っています。

とりあえずソースコードを示します。

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Windows.Forms;
using WindowsLive.Writer.Api;
using WindowsLive.Writer.BlogClient;
using WindowsLive.Writer.BlogClient.Clients;
using WindowsLive.Writer.PostEditor;
using WindowsLive.Writer.Extensibility.BlogClient;

using WriterMshtml = WindowsLive.Writer.Mshtml;

namespace SharpLab.WPCustomFieldsEditor {
    [WriterPlugin("0aaad6ce-da8b-4f78-a73c-c73f3c6c163d", "WPCustomFieldsEditor", PublisherUrl = "http://www.sharplab.net/")]
    public class PublishObserver : PublishNotificationHook {
        public override bool OnPrePublish(System.Windows.Forms.IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
            Blog blog = new Blog(postEditorForm.CurrentBlogId);

            //publishingContextからリフレクションでBlogPostEditingManagerを取得
            FieldInfo fieldInfo = publishingContext.GetType().GetField("_editingContext", BindingFlags.NonPublic | BindingFlags.Instance);
            BlogPostEditingManager manager = (BlogPostEditingManager)fieldInfo.GetValue(publishingContext);
            BlogPost blogPost = (BlogPost)publishingContext.PostInfo;

            blogPost.Title = "test";//エントリ内容への操作

            manager.EditPost(new BlogPostEditingContext(postEditorForm.CurrentBlogId, blogPost));

            return true;
        }

        private PostEditorForm getPostEditorForm(IWin32Window postProgressForm) {
            return (PostEditorForm)((Form)Form.FromHandle(postProgressForm.Handle)).Owner;
        }
    }
}

細かく見ていきましょう。

            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);

この行ではPostEditorFormクラスのインスタンスを取得しています。前エントリ参照。

           Blog blog = new Blog(postEditorForm.CurrentBlogId);

この行ではBlogクラスのインスタンスを取得しています。前エントリ参照。

            FieldInfo fieldInfo = publishingContext.GetType().GetField("_editingContext", BindingFlags.NonPublic | BindingFlags.Instance);
            BlogPostEditingManager manager = (BlogPostEditingManager)fieldInfo.GetValue(publishingContext);

imageここでは、BlogPostEditingManagerクラスのインスタンスを取得してます。OnPrePublishメソッドの引数として渡されたpublishingContextにはBlogPostHtmlEditorクラス(WindowsLive.Writer.PostEditor.PostHtmlEditing名前空間に所属)のインスタンスが格納されており、その_editingContextというパブリックでないフィールドにBlogPostEditingManagerが格納されています。BlogPostHtmlEditorクラス自体もパブリックなクラスではないので、ここではリフレクションで取得しています。なお、BlogPostEditingManagerクラスはエントリを編集画面に読み込んだり、削除したりできるクラスです。正直、自分も良く分かっていません(笑)。

 

            BlogPost blogPost = (BlogPost)publishingContext.PostInfo;

ここでは編集対象のエントリを表すBlogPostクラスのインスタンスを取得しています。前エントリ参照。

            blogPost.Title = "test";//エントリ内容への操作

エントリ内容への書き換えをここで行うことが出来ます。この例ではタイトルの書き換えをしています。試したわけではありませんが、カテゴリや概要に対して変更を加えることもできる筈です。

            manager.EditPost(new BlogPostEditingContext(postEditorForm.CurrentBlogId, blogPost));

そして、書き換えた後の大事な後始末、書き換えたエントリのPostEditorEormへの再読み込みをここで行っております。BlogPostEditingManagerクラスのEditPostメソッドに、それっぽい引数を与えて呼び出せば読み込んでくれるようです。

Comments :2

JZ5 08-07-31 21:13:02 UTC

なるほどー。すごいなー。私は検証というほどしてませんw
まったく試してない発言なのだけど、OpenPostの方は使えなさげ? 勝手に投稿時に編集して、それを開くとWLWにも反映されるみたいなこともできるのかなーと思いました。試さなくていいですよw

shiroica 08-08-01 17:17:48 UTC

OpenPostはどうもよく分からないんですよね。呼んでみても画面に変化が見られなくて。
>勝手に投稿時に編集して、それを開くとWLWにも反映される
プラグインから編集した上で投稿したエントリを、WLWでサーバーからDLして開く、ということでしょうか?試してみますw

Trackbacks : 2

Trackback URL for this entry
http://blog.sharplab.net/blog/2008/07/31/433/trackback/

Listed below are links to weblogs that reference this entry

ピンバック from SharpLab. - publish notification hooksプラグインに関する試行錯誤の続き 08-08-02 09:23:59 UTC

[…] 「SharpLab. – publish notification hooksでpost内容を安全に書き換えるには」のコメント欄を受けて、「サーバーに修正後のエントリをアップ、そのアップされたエントリをWLWでDLして再読み込み […]

ピンバック from Windows Live Writerのプラグインから編集中のエントリのメタ情報を書き換える方法 - SharpLab. 08-09-11 22:55:50 UTC

[…] の内容を書き換えられないか何度か試行錯誤してきましたが(publish notification hooksでpost内容を安全に書き換えるには – SharpLab.など)、 WLW 自体は書き換えられることを想定してないので、 […]