<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SharpLab. &#187; WindowsLiveWriter</title>
	<atom:link href="http://blog.sharplab.net/category/computer/cprograming/windowslivewriter/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sharplab.net</link>
	<description>Shiroicaが学び、経験したことを綴る個人サイト。</description>
	<lastBuildDate>Thu, 28 Jan 2010 17:48:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>WPCustomFieldsEditor更新</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/3029/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/3029/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 08:13:29 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WPCustomFieldsEditor]]></category>
		<category><![CDATA[Windows Live Writer]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/?p=3029</guid>
		<description><![CDATA[動かなくなったまま放置していたWPCustomFieldsEditor、修正したものと差し替えました。WPCustomFieldsEditorは、その名の通り、WordPressのカスタムフィールドを修正するためのWin [...]]]></description>
			<content:encoded><![CDATA[<p>動かなくなったまま放置していた<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/789/">WPCustomFieldsEditor</a>、修正したものと差し替えました。WPCustomFieldsEditorは、その名の通り、WordPressのカスタムフィールドを修正するためのWindows Live Writerのプラグインです。</p>
<p>Windows Live Writerがアップデートしたら動かなくなっていたのは、横着してWLWの内部的なアセンブリを直接参照した時点でまぁ予見出来た話ではあるのですが･･･。今回はちゃんとリフレクションで書き直しております。また、WordPressとのやり取りも、WP-XML-RPCLib2で行うように変更しました。</p>
<p><a href="http://depot.sharplab.net/CSharp/WLWPlugin/WPCustomFieldsEditor.zip">WPCustomFieldsEditor.zip</a></p>
<p>ソースコード：<a href="http://depot.sharplab.net/CSharp/WLWPlugin/WPCustomFieldsEditor.sln.zip">WPCustomFieldsEditor.sln.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/3029/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>セルクマプラグイン</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/selkmaplugin/1230/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/selkmaplugin/1230/#comments</comments>
		<pubDate>Sat, 04 Oct 2008 04:08:04 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[SelkmaPlugin]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Hatena]]></category>
		<category><![CDATA[Hatena Bookmark]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/?p=1230</guid>
		<description><![CDATA[これは何？
エントリの投稿時に、はてなブックマークに当該エントリを保存する機能を、Windows Live Writerに追加するプラグインです。
ダウンロード
SelkmaPluginSetup.zip
動作環境

M [...]]]></description>
			<content:encoded><![CDATA[<h3>これは何？</h3>
<p>エントリの投稿時に、はてなブックマークに当該エントリを保存する機能を、Windows Live Writerに追加するプラグインです。</p>
<h3>ダウンロード</h3>
<p><a href="http://depot.sharplab.net/CSharp/WLWPlugin/SelkmaPluginSetup.zip">SelkmaPluginSetup.zip</a></p>
<h3>動作環境</h3>
<ul>
<li>Microsoft Windows XP SP2 以降または Windows Vista（Windows Live Writerに準拠） </li>
<li>Microsoft .NET Framework 2.0以上 </li>
<li>Windows Live Writer Beta（Build14.0.5025.904) </li>
</ul>
<p>※現在、<a href="http://windowslivewriter.spaces.live.com/blog/cns%21D85741BB5E0BE8AA%211508.entry">Writer Zone</a>で配布されているTechnical Preview版では、おそらく動作しなくなっています。ご注意ください。</p>
<h3>インストール方法</h3>
<p>ダウンロードしたファイルを展開してsetup.exeを実行してください。</p>
<h3>アンインストール方法</h3>
<p>コントロールパネルのプログラムの追加と削除からSelkmaPluginを選択し削除してください。</p>
<h3>操作説明</h3>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/10/image7.png" rel="lightbox"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; margin-left: 0px; border-left: 0px; margin-right: 0px; border-bottom: 0px" height="119" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/10/image-thumb7.png" width="304" align="left" border="0" /></a>エントリの投稿を行うと、スプラッシュウィンドウに続いてブックマークコメントの編集画面が現れます。[OK]を押せばブックマークされ、[Cancel]を押せばエントリの投稿だけが行われます。 </p>
<hr class="clear-both" />
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/10/image61.png" rel="lightbox"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; margin-left: 0px; border-left: 0px; margin-right: 0px; border-bottom: 0px" height="127" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/10/image6-thumb.png" width="284" align="right" border="0" /></a> また、初回実行時には、ブックマークする際に使うはてなのアカウントを尋ねるダイアログが表示されます。使いたいアカウントのユーザー名とパスワードを正しく入力してください。設定したはてなのアカウント情報を後で変更したい場合は、WLWのオプションのプラグインの項から編集することが出来ます。 </p>
<h3>謝辞</h3>
<p>はてなブックマークに追加する処理の部分は、JZ5さんの<a href="http://blogs.wankuma.com/katamari/archive/2008/07/27/150566.aspx">はてブをプログラムから追加する</a>というエントリのコードを参考にさせて頂きました。有難うございました。</p>
<h3>ソースコード</h3>
<p><a href="http://depot.sharplab.net/CSharp/WLWPlugin/SelkmaPluginSln.zip">SelkmaPluginSln.zip</a></p>
<h3>更新履歴</h3>
<ul>
<li>2008-10-04 イニシャルリリース </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/selkmaplugin/1230/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPCustomFieldsEditor書き直し</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/1185/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/1185/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 16:18:04 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WPCustomFieldsEditor]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/1185/</guid>
		<description><![CDATA[先日WPCustomFieldsEditorが正常に動作しないというコメントがあり、良い機会なのでBugFixも兼ねてWordPressとXML-RPC APIを通じて遣り取りを行う部分を書き直してみました。これまでは文字列連結でリクエスト用のXMLを捻り出してなんとか凌いでいたのですが、WindowsLive.Writer.CoreServices.dllにXML-RPC Clientライブラリがあるのを見つけたので、今回はそのお世話になることに。WLWのプラグインを作る分には怒られないんじゃないかな･･･？
で、以下が書き直した後のOnPostPublishメソッドのソースコード。

        public override void OnPostPublish(IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
            Blog blog = new Blog(postEditorForm.CurrentBlogId);
   [...]]]></description>
			<content:encoded><![CDATA[<p>先日WPCustomFieldsEditorが正常に動作しないというコメントがあり、良い機会なのでBugFixも兼ねてWordPressとXML-RPC APIを通じて遣り取りを行う部分を書き直してみました。これまでは文字列連結でリクエスト用のXMLを捻り出してなんとか凌いでいたのですが、WindowsLive.Writer.CoreServices.dllにXML-RPC Clientライブラリがあるのを見つけたので、今回はそのお世話になることに。WLWのプラグインを作る分には怒られないんじゃないかな･･･？</p>
<p>で、以下が書き直した後のOnPostPublishメソッドのソースコード。</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7d5bbe9e-0adb-4958-a434-f87837ac6cb5" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">        public override void OnPostPublish(IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
            Blog blog = new Blog(postEditorForm.CurrentBlogId);
            PropertyInfo propInfo = blog.GetType().GetProperty("BlogClient", BindingFlags.NonPublic | BindingFlags.Instance);
            IBlogClient blogClient = (IBlogClient)propInfo.GetValue(blog, null);

            WordPressClient xmlRpcClient = blogClient as WordPressClient;
            if (xmlRpcClient != null &amp;&amp; !publishingContext.PostInfo.IsPage) {

                const string userAgent = "WPCustomFieldEditor";

                XmlRpcString postId = new XmlRpcString(publishingContext.PostInfo.Id);
                XmlRpcString userName = new XmlRpcString(xmlRpcClient.Username);
                XmlRpcString password = new XmlRpcString(xmlRpcClient.Password);

                HttpRequestFilter filter = delegate(System.Net.HttpWebRequest request) {
                };
                XmlRpcClient client = new XmlRpcClient(blog.PostApiUrl, userAgent, filter, xmlRpcClient.Options.CharacterSet);
                XmlRpcMethodResponse res = client.CallMethod("metaWeblog.getPost", postId, userName, password);
                if (res.FaultOccurred) {
                    showErrorMessage(dialogOwner, res.FaultString);
                    return;
                }

                XmlNodeList customFieldsNodes = res.Response.SelectNodes("//struct/member[name="custom_fields"]/value/array/data/value/struct");

                CustomField[] customFields = new CustomField[customFieldsNodes.Count];
                for (int i = 0; i &lt; customFieldsNodes.Count; i++) {
                    XmlNode item = customFieldsNodes[i];
                    customFields[i] = new CustomField();
                    customFields[i].Id = item.SelectSingleNode("member[name="id"]/value/string").InnerText;
                    customFields[i].Key = item.SelectSingleNode("member[name="key"]/value/string").InnerText;
                    customFields[i].Value = item.SelectSingleNode("member[name="value"]/value/string").InnerText;
                }

                WPCustomFieldsEditor fieldEditor = new WPCustomFieldsEditor(customFields, this.Options);
                DialogResult result = fieldEditor.ShowDialog(dialogOwner);
                if (result == DialogResult.OK) {

                    Func getRpcMemberValue = delegate(string name) {
                        return res.Response.SelectSingleNode("//struct/member[name="" + name + ""]/value/*").InnerText;
                    };

                    XmlRpcStruct[] cv = new XmlRpcStruct[fieldEditor.CustomFields.Length];
                    for (int i = 0; i &lt; cv.Length; i++) {
                        CustomField sourceItem = fieldEditor.CustomFields[i];
                        List&lt;XmlRpcMember&gt; structMember = new List&lt;XmlRpcMember&gt;();
                        if(!string.IsNullOrEmpty(sourceItem.Id)){
                            structMember.Add(new XmlRpcMember("id", sourceItem.Id));
                        }
                        if(!string.IsNullOrEmpty(sourceItem.Key)){
                            structMember.Add(new XmlRpcMember("key", sourceItem.Key));
                        }
                        structMember.Add(new XmlRpcMember("value", sourceItem.Value));
                        cv[i] = new XmlRpcStruct(structMember.ToArray());
                    }

                    XmlRpcStruct content = new XmlRpcStruct(new XmlRpcMember[]{
                        new XmlRpcMember("title",getRpcMemberValue("title")),
                        new XmlRpcMember("description",getRpcMemberValue("description")),
                        new XmlRpcMember("mt_text_more",getRpcMemberValue("mt_text_more")),
                        new XmlRpcMember("mt_allow_comments",getRpcMemberValue("mt_allow_comments")),
                        new XmlRpcMember("mt_allow_pings",getRpcMemberValue("mt_allow_pings")),
                        new XmlRpcMember("mt_keywords",getRpcMemberValue("mt_keywords")),
                        new XmlRpcMember("wp_slug",getRpcMemberValue("wp_slug")),
                        new XmlRpcMember("wp_password",getRpcMemberValue("wp_password")),
                        new XmlRpcMember("wp_author_id",getRpcMemberValue("wp_author_id")),
                        new XmlRpcMember("mt_excerpt",getRpcMemberValue("mt_excerpt")),
                        new XmlRpcMember("mt_keywords",getRpcMemberValue("mt_keywords")),
                        new XmlRpcMember("custom_fields",new XmlRpcArray(cv))
                        });
                    XmlRpcBoolean isPublish = new XmlRpcBoolean(publish);

                    res = client.CallMethod("metaWeblog.editPost", postId, userName, password, content, isPublish);
                    if (res.FaultOccurred) {
                        showErrorMessage(dialogOwner, res.FaultString);
                        return;
                    }
                }

            }

        }</pre>
</div>
<p>WLWによるエントリの投稿が終わった後に呼び出され、サーバーからその投稿されたエントリのデータを取得し（20行目付近）、それに基づいてカスタムフィールドのデータを付加したエントリのデータを作成して投げ直すという流れ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/1185/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WLWプラグイン登録用レジストリについてのメモ書き</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1160/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1160/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 02:21:27 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/1160/</guid>
		<description><![CDATA[Windows Live WriterのプラグインをWLWに登録する場合、


HKEY_LOCAL_MACHINESOFTWAREWindows LiveWriterPluginAssemblies
HKEY_CURR [...]]]></description>
			<content:encoded><![CDATA[<p>Windows Live WriterのプラグインをWLWに登録する場合、</p>
</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:6902a68d-e5f7-4b44-a5d9-4e6c9f070e39" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c:nogutter">HKEY_LOCAL_MACHINESOFTWAREWindows LiveWriterPluginAssemblies
HKEY_CURRENT_USERSOFTWAREWindows LiveWriterPluginAssemblies
</pre>
</div>
<p>以上の二つのレジストリのいずれかの下にアセンブリの場所を示す文字列値を追加すれば良い、と<a href="http://msdn.microsoft.com/en-us/library/aa738841.aspx">MSDNでは書かれている</a>のですが、これは間違いで、</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:ddd7da0b-2e35-4ec9-b0f8-686dc797953a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c:nogutter">HKEY_LOCAL_MACHINESOFTWAREWindows Live　WriterPluginAssemblies
HKEY_CURRENT_USERSOFTWAREWindows Live　WriterPluginAssemblies
</pre>
</div>
<p>でなければならないようです。<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/789/">WPCustomFieldsEditor</a>のバグフィックスの過程で気づきました。MSDN…。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1160/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>InsertTegakiPlugin v1.1.0.0</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1134/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1134/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 10:58:45 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/1134/</guid>
		<description><![CDATA[InsertTegakiPlugin v1.1.0.0がリリースされています。これは個人的に気に入っているプラグインで、

daruyanagiさん、変な使い方してごめんなさい。   でもalt属性も別に編集できるように [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.be-styles.jp/archives/1665">InsertTegakiPlugin v1.1.0.0</a>がリリースされています。これは個人的に気に入っているプラグインで、</p>
<div class="wlWriterEditableSmartContent" id="scid:7f6cb4f3-53ee-4ec9-9945-1f84fce7a1cc:6b7755d7-6e37-49d0-ac4b-117af0326dda" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"><img src="http://blog.sharplab.net/wp-content/uploads/2008/09/tegaki1.png" alt="　 　　　　 　　 ＿＿＿_ / 　　　　　　 ／ ＼ 　 ／＼　 ｷﾘｯ / .　　　　　／　（ー） 　（ー）＼ / 　　　　／　　 ⌒（__人__）⌒ ＼　なぜなら、AAを画像化して / 　　　　|　　 　　　|r┬-|　　　　|　環境によらず崩れないように出来るからです。 / 　　　　 ＼　　　　 `ー'&#180;　　 ／　 / 　　　　ノ　　　　　　　　　　　　＼ 　　 /  / 　　 ／￣￣＼ / 　／　　 _ノ　　＼ / 　|　　　 （ ●）（●） 　ぜったい / .　|　　　　 （__人__）　　使い方間違ってるだろ / 　 |　　　　　｀ ⌒&#180;ﾉ / .　 |　　　　　　 　 }　　ミ　　　　　　　　ﾋﾟｺｯ / .　 ヽ　　　　　 　 }　ミ　 ／＼　　,☆＿＿__ / 　　 ヽ　　　　　ノ　　　　＼　 ＼ ／　　 　　＼ / 　　　/　　　 く　　＼.　　／＼／　─　 　 ─　＼ 　てへｗ / 　　　|　　　　　`ー一⌒)　 ／ 　 （●） 　（●）　 ＼ / 　 　 |　　　　i&#180;￣￣￣ ＼ |　 　 　 （__人__）　　 　 | / 　　　　　　　　　　　　　　　＼＿　　 ｀ ⌒&#180;　 　　／ / 　　　　　　　　　　　　　　　　／　　　 　　　　　　＼" /></div>
<p>daruyanagiさん、変な使い方してごめんなさい。   <br />でもalt属性も別に編集できるようにしてくれるとありがたいです(ｺﾗ</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1134/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>BlogThisPluginよもやま話</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1131/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1131/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 09:52:11 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[BlogThisPlugin]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1131/</guid>
		<description><![CDATA[ とりあえずWindows Live Photo Galleryのプラグインを作るぞー！ということでサクッと作ってみたBlogThisPlugin。書くことが無さ過ぎて、前のエントリは無駄に英語で書いてみたりしてみました [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/09/image10.png" rel="lightbox"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin-left: 0px; margin-right: 0px; border-right-width: 0px" height="184" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/09/image-thumb10.png" width="304" align="right" border="0" /></a> とりあえずWindows Live Photo Galleryのプラグインを作るぞー！ということでサクッと作ってみた<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1128/">BlogThisPlugin</a>。書くことが無さ過ぎて、<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1128/">前のエントリ</a>は無駄に英語で書いてみたりしてみましたが、このエントリでは、このBlogThisPluginを作るにあたって<a href="http://msdn.microsoft.com/en-us/library/cc967070.aspx">Windows Live Photo Gallery Publishing Plug-in Platform</a>を調べて分かったことを記したいと思います。ちなみに、Windows Live Photo Gallery Publishing Plug-in PlatformとはWindows Live Photo Galleryの拡張をホストする機能のことで、これを使えば「投稿」メニューに独自の項目を追加することが出来ます。</p>
<p>Windows Live Photo GalleryのPublishing Plug-in（以下Publishing Plug-in）の作成は<a href="http://msdn.microsoft.com/en-us/library/cc967062.aspx">IPublishPlugin Interface</a>を実装したクラスを作成し、そのアセンブリのパスや<a href="http://msdn.microsoft.com/en-us/library/cc967062.aspx">IPublishPlugin Interface</a>を実装したクラスの完全限定名などを<a href="http://msdn.microsoft.com/en-us/library/cc967074.aspx">Publishing Plug-in Registry Settings</a>に従ってレジストリに登録すれば出来上がり、という流れです。属性を活用していたWLWに比べると、ちょっとレガシーですね。<a href="http://msdn.microsoft.com/en-us/library/cc967062.aspx">IPublishPlugin Interface</a>を実装するにあたっては<a href="http://msdn.microsoft.com/en-us/library/cc967073.aspx">Publishing Plug-in Architecture</a>を参照し、どのメソッドがどのタイミングで呼び出されるかを確認するとよいでしょう。メソッドの呼び出しの合間に、Live Photo Galleryが進捗状況を表示するダイアログを挟みこんできたりするので…。また、Publishing Plug-in Platformは、IPublishPluginのメソッドを呼び出す際、<a href="http://msdn.microsoft.com/en-us/library/cc967062.aspx">IPublishPlugin Interface</a>を実装したクラスのインスタンスを使いまわさず、インスタンスを生成し直してくる場合があるので、その点にも注意した方がよいでしょう。</p>
<p>折角なので、BlogThisPluginのソースコードを晒してみます。</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:39505842-5f3f-4ffe-89b5-6dc4ee66ced9" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Microsoft.WindowsLive.PublishPlugins;
using WindowsLive.Writer.Api;

namespace SharpLab.BlogThisPlugin {
    public class PublishPlugin : IPublishPlugin{

        public bool HasPublishResults(System.Xml.XmlDocument sessionXml) {
            throw new NotImplementedException();
        }

        public bool HasSummaryInformation(System.Xml.XmlDocument sessionXml) {
            throw new NotImplementedException();
        }

        public void LaunchPublishResults(System.Xml.XmlDocument sessionXml) {
            throw new NotImplementedException();
        }

        public bool PublishItem(System.Windows.Forms.IWin32Window parentWindow, string mediaObjectId, System.IO.Stream stream, System.Xml.XmlDocument sessionXml, IPublishProperties publishProperties, IPublishProgressCallback callback, System.Threading.EventWaitHandle cancelEvent) {
            throw new NotImplementedException();
        }

        public void ShowSummaryInformation(System.Windows.Forms.IWin32Window parentWindow, System.Xml.XmlDocument sessionXml) {
            throw new NotImplementedException();
        }

        public bool ShowConfigurationSettings(System.Windows.Forms.IWin32Window parentWindow, System.Xml.XmlDocument sessionXml, System.Xml.XmlDocument persistXml, IPublishProperties publishProperties) {
            if(!WriterApplication.IsInstalled){
                System.Windows.Forms.MessageBox.Show(parentWindow, "Windows Live Writer is not Installed.", "BlogThis Plugin",
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
            else{
                blogThis(parentWindow, sessionXml);
            }
            return false;
        }

        private void blogThis(System.Windows.Forms.IWin32Window parentWindow, System.Xml.XmlDocument sessionXml) {
                XmlNodeList items = sessionXml.SelectNodes("/PhotoGalleryPublishSession/ItemSet/Item[PerceivedType="image"]/FullFilePath");
            if(items.Count==0){
                System.Windows.Forms.MessageBox.Show(parentWindow, "Please select at least one image.", "BlogThis Plugin",
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                return;
            }
            string[] fileNames = new string[items.Count];
                for (int i = 0; i &lt; items.Count; i++) {
                    fileNames[i] = items[i].InnerText;
                }
                WriterApplication writer = new WriterApplication();
                writer.BlogThisImageFileList(null, fileNames, null);            

        }
    }
}</pre>
</div>
<p>うわぁNotImplementedExceptionばっか。。。BlogThisPluginでは、最初に呼び出されるShowConfigurationSettingsメソッドの段階でfalseを返してしまうことにしました。これは、写真のアップロードを直接するわけではないため、Live Photo Galleryの挟みこんでくるダイアログが邪魔だったからです。まぁ、こういうのもありかもね、ということで。そのうちにPublishing Plug-inのアーキテクチャに沿ってWordPressにXMLRPC-APIを使って画像やらを投稿するプラグインも試作してみたいと思います。</p>
<p>ちなみにソリューション全体はこちらにアップしています。<br />
  <br /><a href="http://depot.sharplab.net/CSharp/WLWPlugin/BlogThisPluginSln.zip">http://depot.sharplab.net/CSharp/WLWPlugin/BlogThisPluginSln.zip</a> </p>
<p>真っ当に実装された<a href="http://msdn.microsoft.com/en-us/library/cc967071.aspx">MS謹製のFlickerのプラグイン</a>より簡単に弄れるたたき台としてどうぞ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1131/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>BlogThisPlugin</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1128/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1128/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 07:59:43 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[BlogThisPlugin]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1128/</guid>
		<description><![CDATA[What&#8217;s this?
This is a simple plugin that adds “BlogThis” menu to Windows Live Photo Gallery. You can click this menu and launch Windows Live Writer with a new BlogThis post that contains selected images.
Download
BlogThisPluginSetup.zip
System Requirements

Microsoft Windows XP SP2 or later, or Windows Vista 
Minimum 512 MB of RAM (based on the profile of Windows Live [...]]]></description>
			<content:encoded><![CDATA[<h3>What&#8217;s this?</h3>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/09/image8.png" rel="lightbox"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" align="right" src="http://blog.sharplab.net/wp-content/uploads/2008/09/image-thumb8.png" width="244" height="201" /></a>This is a simple plugin that adds “BlogThis” menu to Windows Live Photo Gallery. You can click this menu and launch Windows Live Writer with a new BlogThis post that contains selected images.</p>
<h3>Download</h3>
<p><a href="http://depot.sharplab.net/CSharp/WLWPlugin/BlogThisPluginSetup.zip">BlogThisPluginSetup.zip</a></p>
<h3>System Requirements</h3>
<ul>
<li>Microsoft Windows XP SP2 or later, or Windows Vista </li>
<li>Minimum 512 MB of RAM (based on the profile of Windows Live Photo Gallery) </li>
<li>Microsoft .NET Framework 2.0 or higher </li>
<li>Latest version of Windows Live Photo Gallery </li>
<li>Latest version of Windows Live Writer </li>
</ul>
<h3><a href="http://blog.sharplab.net/wp-content/uploads/2008/09/image9.png" rel="lightbox"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" align="right" src="http://blog.sharplab.net/wp-content/uploads/2008/09/image-thumb9.png" width="244" height="222" /></a>How to install</h3>
<p>Please unzip BlogThisPluginSetup.zip, and execute setup.exe.</p>
<h3>How to uninstall</h3>
<p>Please uninstall by “Add or Remove Programs” utility in the Control Panel.</p>
<h3>Releases</h3>
<p>2008-09-23 Initial version released.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/blogthisplugin/1128/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Windows Live Writer Beta(Build14.0.5025.904)</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1085/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1085/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 16:59:04 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/1085/</guid>
		<description><![CDATA[Windows Live Wave3のBetaアプリ群がDL出来るようになった、ということなので、早速Windows Live Writerの新版を入れてみた。Wave 3: Windows Live Writer –  [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.wankuma.com/katamari/archive/2008/09/17/156831.aspx"></a><a href="http://blog.sharplab.net/wp-content/uploads/2008/09/image5.png" rel="lightbox"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin-left: 0px; margin-right: 0px; border-right-width: 0px" height="234" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/09/image-thumb5.png" width="304" align="left" border="0" /></a><a href="http://blogs.wankuma.com/katamari/archive/2008/09/17/156831.aspx">Windows Live Wave3のBetaアプリ群がDL出来るようになった</a></a>、ということなので、早速Windows Live Writerの新版を入れてみた。<a title="http://www.liveside.net/main/archive/2008/09/17/wave-3-windows-live-writer-a-first-look.aspx" href="http://www.liveside.net/main/archive/2008/09/17/wave-3-windows-live-writer-a-first-look.aspx">Wave 3: Windows Live Writer – A First Look &#8211; LiveSide &#8211; News blog &#8211; LiveSide &#8211; Windows Live news and interviews</a>というレビュー記事によれば、CTP版からの大きな機能追加はされていない模様。実際、プラグイン関係でも、オブジェクトブラウザでWindowsLive.Writer.Api以下を覗いて見ても特に違いは見つけられなかった。但し、WLWの動画の貼り付け機能の動画の投稿先/既存の動画の選択元のオプションとしてYouTubeが追加されたのは結構便利かも。 </p>
<p>しかし画面のデザインはWave 3に合わせる形で、変更が加えられたようだ。CTP版からGUI要素の位置には変更がないようだが、色遣いや区切り線の入れ方が変わっている。正直なところを言うと、CTP版の頃の方が自分は良かった…。 </p>
<hr class="clear-both" /><a href="http://blog.sharplab.net/wp-content/uploads/2008/09/image7.png" rel="lightbox"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin-left: 0px; margin-right: 0px; border-right-width: 0px" height="364" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/09/image-thumb7.png" width="604" border="0" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1085/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Live Writerのプラグインから編集中のエントリのメタ情報を書き換える方法</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1066/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1066/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 13:55:45 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/uncategorized/1066/</guid>
		<description><![CDATA[これまでPublish Notification Hook プラグインで、投稿前にエントリの内容を書き換えられないか何度か試行錯誤してきましたが（publish notification hooksでpost内容を安全に [...]]]></description>
			<content:encoded><![CDATA[<p>これまでPublish Notification Hook プラグインで、投稿前にエントリの内容を書き換えられないか何度か試行錯誤してきましたが（<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/433/">publish notification hooksでpost内容を安全に書き換えるには &#8211; SharpLab.</a>など）、</p>
<blockquote><p>WLW 自体は書き換えられることを想定してないので、プラグインから書き換えても投稿後にエディタ中の表示は変化しません。</p>
<p><cite><a href="http://blogs.wankuma.com/katamari/archive/2008/07/17/149230.aspx">Publish Notification Hook プラグイン 値の書き換え-katamari.wankuma.com</a></cite></p>
</blockquote>
<p>という問題などに行き当たったりしてきました。そこで、今回はエントリのメタ情報を編集するためのGUIコントロールのインスタンスのプロパティを弄ることで画面の書き換えも行ってみました。適用できる部分は限られ、根本的な解とは言い難いですが、参考まで。</p>
<p>今回は例としてタグの設定を行ってみたいと思います。</p>
<h3>Textboxのインスタンスの取得方法</h3>
<p>さて、操作の対象としたいWLW下部のプロパティパネルにあるタグ設定用のTextBoxですが、これのインスタンスのNameプロパティの値が分かれば、</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b9fc58d2-842c-45b3-81ae-4f84fdff2e19" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">private static Control findControlByName(Control control, string controlName) {
    foreach (Control cChild in control.Controls) {
        if (cChild.Name == controlName) {
            return cChild;
        }
        if (cChild.HasChildren) {
            Control returned = findControlByName(cChild, controlName);
            if (returned != null) {
                return returned;
            }
        }
    }
    return null;
}</pre>
</div>
</p>
<p>上のようなメソッドを用意することでトップレベルのコントロールから包含関係を伝ってインスタンスを取得することが出来ます。</p>
<p>ではそのNameプロパティの値ですが、今回はWLWのプラグインにアタッチさせたVisual Studioのローカル変数ウィンドウからコントロールのツリー構造を辿って調べる方法ではなく、Managed Spyというツールを使って調べる方法を紹介してみたいと思います。</p>
<h3>Managed Spy</h3>
<p>ManagedSpy は、別プロセス内のマネージドコントロールのプロパティおよびイベントの表示・編集を行えるツールで、<a href="https://www.microsoft.com/japan/msdn/msdnmag/issues/06/04/ManagedSpy/default.aspx">MSDN Magazineの06年4月号の記事</a>（<a href="http://msdn.microsoft.com/en-us/magazine/cc163617.aspx">原文、但しツールへのリンク消滅</a>）と共に配布されています。SPY++のマネージド版という説明がよくなされているようですが、自分はSPY++を触ったことがないのでよく分かりません＞＜。</p>
<p>なお、別プロセス内のマネージドコントロールにアクセスする方法はmanaged C++で書かれたManagedSpyLibというライブラリが提供しているようです。ソースコードの提供もされているので、興味があれば覗いてみると良いのではないでしょうか。</p>
</p>
</p>
<p>話をManaged Spyを使ったWLWのコントロールの調査に戻します。WLWを起動後、Managed Spyを起動すると、 <a href="http://blog.sharplab.net/wp-content/uploads/2008/09/image.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/09/image-thumb.png" width="213" align="right" border="0" /></a>図のようなウィンドウが開きます。左側のツリービューには起動中のマネージドアプリの一覧が表示され、ツリーを展開してゆくことでコントロールのツリー構造を調べてゆくことが出来ます。選択しているツリーのノードがどのコントロールと対応しているかを見たい場合は、メニューから「Show Window」というメニューを実行してやれば、FirefoxのDOM InspectorやFirebugのように、選択されたコントロールを囲む形で矩形を表示させることが出来ます。 </p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/09/image1.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/09/image-thumb1.png" width="213" align="left" border="0" /></a>さて、そうやって発見したのがこのtextBoxKeywordsという名前のTextBox。コントロールのインスタンスの名前をアタッチさせたVSから調べるのはなかなか骨の折れる作業ですが、Managed Spyを使えば大分楽に出来ました。</p>
<p>なお、右側のVisual Studioのプロパティウィンドウのようなビューは表示だけでなくプロパティの編集も可能なので、WLWに対して色々イタズラをすることも可能です。<br />
  <br />例えばエディタ部分を非表示にしてみた例。…だからどうしたって感じですが（笑）</p>
<hr class="clear-both" />
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/09/image14.png" rel="lightbox"><img title="image" style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/09/image14-thumb.png" width="404" border="0" /></a> </p>
<h3>実際に書き換えてみる</h3>
</p>
<p>後は簡単です。こんな感じのコードでタグの書き換えが出来ます。</p>
</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:920316ed-ac5c-4705-815e-125ae2a243c1" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">public override bool OnPrePublish(System.Windows.Forms.IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

    PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
    TextBox textBoxKeywords = (TextBox)findControlByName(postEditorForm, "textBoxKeywords");
    textBoxKeywords.Text = "SampleTag";
    ((BlogPost)publishingContext.PostInfo).Keywords = textBoxKeywords.Text;
    return true;
}</pre>
</div>
<p>3行目、6行目については、<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/386/">中まで見よう！Windows Live Writer &#8211; Sharplab.</a>のエントリを参照してください。</p>
<p>なお、用意したテスト用コード全文は以下の通りです。</p>
<div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d4aa7e0d-6169-442f-a977-9de07296fc5b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:collapse">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;

namespace PublishNotificationHooksTestbedPlugin {
    [WriterPlugin("95c3d56c-671a-46a0-8bef-3d064d85867e", "PNHTestbedPlugin", PublisherUrl = "http://www.sharplab.net/")]
    public class PublishNotificationHooksTestbedPlugin : PublishNotificationHook {
        public override bool OnPrePublish(System.Windows.Forms.IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
            TextBox textBoxKeywords = (TextBox)findControlByName(postEditorForm, "textBoxKeywords");
            textBoxKeywords.Text = "SampleTag";
            ((BlogPost)publishingContext.PostInfo).Keywords = textBoxKeywords.Text;
            return true;
        }

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

        private static Control findControlByName(Control control, string controlName) {
            foreach (Control cChild in control.Controls) {
                if (cChild.Name == controlName) {
                    return cChild;
                }
                if (cChild.HasChildren) {
                    Control returned = findControlByName(cChild, controlName);
                    if (returned != null) {
                        return returned;
                    }
                }
            }
            return null;
        }
    }
}
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/1066/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Live Writerでテーマが崩れる場合の対処法</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/989/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/989/#comments</comments>
		<pubDate>Sat, 30 Aug 2008 16:19:14 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/989/</guid>
		<description><![CDATA[ WindowsLiveWriterの編集画面にウェブサイトのテーマを適用する場合、テーマが崩れて困ることがあります。例えばこのサイトの新デザインもWLW対策を取らなければ右SSのように酷い状態になってしまいます。むしろ [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image35.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb32.png" width="284" align="right" border="0" /></a> WindowsLiveWriterの編集画面にウェブサイトのテーマを適用する場合、テーマが崩れて困ることがあります。例えばこのサイトの新デザインもWLW対策を取らなければ右SSのように酷い状態になってしまいます。むしろ、崩れなければ僥倖で（打率一割ぐらいかなぁ…）、自分は崩れた時の対応を織り込んでサイトの製作期間を見積るようにしています。</p>
<h3>崩れる原因</h3>
<p>さて、WLWの編集画面ではなぜテーマが崩れてしまうのでしょうか？WLWの描画エンジンがアホの子だから？ノー。WLWのエンジンはTridentです。確かにTridentはアホの子ではありますが、少なくともデファクトスタンダードであるIEと同じ表示になるわけですから、ここでは問題になりません。</p>
</p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image36.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="173" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb33.png" width="244" align="left" border="0" /></a>答は「WLWが編集画面に読み込むページのソースでは記事に関係のない部分、つまりタイトルと本文以外の部分の要素を全て削除してしまうから」です。WLWが取得してきたテーマはC:Users&lt;ユーザー名&gt;AppDataRoamingWindows Live Writerblogtemplates&lt;ブログのGUID？&gt;のどこかに保存されているのですが、それをFirebugでツリー表示したのが左のSSです。 ん～、見事なまでのふたこぶラクダ。タイトルの要素と、本文の要素、そしてそれらを囲む要素だけしか残っていません。ヘッダーやフッター、サイドバーは情け容赦なく消されています。visibility:hiddenが適用されているのではなく、要素自体が残っていません。これにより、その消された要素にレイアウトが依存しているテーマは表示が崩れてしまうのです。このサイトの新デザインも、消された要素によってfloatをclearしていた個所があったので、本文部を囲っているfloat要素の高さがゼロになり、白い背景が伸びずその下の暗色の横ストライプが見えてしまっていました。</p>
<h3>対策</h3>
<p>では、こんな時どうするか。WLWは諦めてしまうにはあまりに便利で惜しいソフトです。何とか対策を考えてみましょう。</p>
<h4>対策1：サイトのテーマを全面的に修正する</h4>
<p>ページのHTMLの構造を書き換える、floatは必ずclearfixでクリアする、など八方手を尽くしてWLW上では消えてしまう要素への依存をなくし、WLW Compatibleなテーマに書き換えるという方策です。これはサイトの設計時点で取り組まないと難しいでしょう。確実ですが、サイトの表現力にも影響を与えますし、本末転倒な気がします。</p>
<h4>対策2:WLWがテーマをDLする時だけサイトのデザインを差し替える</h4>
<p>WLWがテーマをDLする時を見計らって、その時だけstyle属性などでガチガチに固めてWLW対策をしたテーマに差し替えるという方法です。どうせ回り込ませるはずだった要素が消えてしまうなら、その時はfloatも辞めてしまえ、とか対策をします。差し替えはマニュアル操作でもよいですが、WordPressのようにテーマがプログラマブルな場合は、WLWに設定するホームページのURLにwlwcompatiblemode=onなどの適当なgetパラメタを追加し、テーマの側でそのようなパラメタが付加された場合だけWLW対策用のCSSを追加で読み込ませる、といった方法を採ることもできます。（WLWはテーマをWLWの設定でサイトのホームページとして指定したURLの内容から生成するので。）ちなみに自分はこの方法を使っています。</p>
<h3>対策3:ダウンロードされたテーマの書き換え</h3>
<p>ダウンロードされたテーマはC:Users&lt;ユーザー名&gt;AppDataRoamingWindows Live Writerblogtemplates&lt;BlogのGUID？&gt;に保存されると述べましたが、これを編集することでも対処できるようです。ただ、WLWの想定していない操作なので、副作用もあるかもしてないので、注意して行った方が良いでしょう。また、自動でWLWがテーマをウェブサイトから再読み込みして上書きしてしまう場合もあるらしいので、その点にも注意してバックアップを取るなりの対策が必要でしょう。</p>
<h3></h3>
<h3></h3>
<h3>テーマのDLに失敗する場合</h3>
<p>エントリの本題からは少しずれますが、テーマのDLに失敗する場合の原因とその対策で自分が知っているものを一セット紹介してみます。</p>
<p>前述の通り、WLWはテーマをWLWの設定でサイトのホームページとして指定したURLの内容から生成するようです。このとき、ホームページとして設定されたURLに最新記事が表示されない場合は、WLWはどこがタイトルに置き換えるべきところで、どこが本文に置き換えるべきところか判断がつかず、テーマの生成に失敗してしまいます。例えば、WordPressでホームページに最新記事の代わりに固定ページを表示させるようにした場合などがこれにあたります。前述の対策2を行えばよいでしょう。</p>
<h3>おわりに</h3>
<p>以上、WLWでデザインが崩れた際の対応策をまとめてみましたが、いかがだったでしょうか？このエントリがWLWの快適な利用に繋がれば幸いです。</p>
<p>&#160;</p>
<p>しかし…WLWが表示の必要のない要素の扱いを削除からvisibility:hiddenの適用に改めてくれれば多分全て解決するはずなんですけれどねぇ…レイアウトが崩れるリスクを取ってまで要素を削除する理由ってなんなんでしょうかね。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/989/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Live WriterではてなダイアリーAtomPubにチャレンジしてみた。</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/921/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/921/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 03:26:19 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[Atom Pub]]></category>
		<category><![CDATA[Hatena]]></category>
		<category><![CDATA[Hatena Diary]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/?p=921</guid>
		<description><![CDATA[追記：現在はWindows Live Writerが使えるようになったようです。はてなはフットワークが軽くていいですね。
はてなインターンで実装されたというはてなダイアリーのAtom Pub APIを使って、Window [...]]]></description>
			<content:encoded><![CDATA[<p><strong>追記：現在はWindows Live Writerが使えるようになったようです。はてなはフットワークが軽くていいですね。</strong></p>
<p><a href="http://d.hatena.ne.jp/keikubo/20080829/1219966213">はてなインターンで実装された</a>というはてなダイアリーのAtom Pub APIを使って、Windows Live Writerからはてダに投稿できないか試してみました。     <br />結論から先に言ってしまうと、登録出来ませんでした。残念…。 とりあえず、どこで失敗しているっぽいか調べた際のレポートを載せておきます。</p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image32.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="125" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb29.png" width="244" align="left" border="0" /></a>どこで失敗するかというと、Windows Live Writerに新しいアカウントを追加する際。FiddlerでWLWの通信を覗いてみたところ、アカウントの追加画面でBlogのタイプをAtom Pub APIに設定し、エンドポイントURLを入力してやって次の画面に進もうとすると、WLWはそのエンドポイントURLに対してまず認証無しでGETリクエストを投げるようです。当然はてなのAtom Pub APIはこれを拒否し、401 Unauthorizedを返すのですが、<a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image33.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="167" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb30.png" width="216" align="right" border="0" /></a>これに対してWLWは今度はちゃんとWSSE認証のためのヘッダを付けてGETリクエストを送るようです。 良い感じですね。ところがこれに対してはてなAtom Pubは403 Forbiddenを返してきます。なんで？</p>
<p>401 Unauthorizedを返してこないので、認証には成功したようなのですが、ちょっとこれは謎仕様。このためWLWは一つ目のSSのようなダイアログが出てこれ以上登録を進めることが出来なくなります。ん～何が悪いんでしょうかね…。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/921/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>SyntaxHighlighter一部改修メモ</title>
		<link>http://blog.sharplab.net/computer/blog/877/</link>
		<comments>http://blog.sharplab.net/computer/blog/877/#comments</comments>
		<pubDate>Fri, 22 Aug 2008 07:44:58 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[SyntaxHighlighter]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/blog/877/</guid>
		<description><![CDATA[
ソースコードをハイライト表示してくれるので非常に便利なSyntaxHighlighter。JZ5さんがSyntaxHighlighter for Windows Live WriterというプラグインでWLW上でスマー [...]]]></description>
			<content:encoded><![CDATA[</p>
<p>ソースコードをハイライト表示してくれるので非常に便利な<a href="http://code.google.com/p/syntaxhighlighter/">SyntaxHighlighter</a>。JZ5さんが<a href="http://katamari.jp/soulware/index.php/post/syntaxhighlighter">SyntaxHighlighter for Windows Live Writer</a>というプラグインでWLW上でスマートコンテントとして管理できるようにしてくれているので、WLW好きの自分としては是非このBlogにも組み込みたいと思い、作業していたのですが、その中でSyntaxHighlighterの表示の不具合にぶつかりました。今回のエントリではその対応策を記します。 </p>
<h3>SyntaxHighlighterの持つ問題</h3>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image25.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="122" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb22.png" width="298" align="right" border="0" /></a> SyntaxHighlighterは、通常、一行あたりの文字数が多くSyntaxHighlighterの表示部の横幅を超えるようなソースコードの場合、white-space:normal;の指定により、折り返し表示してくれるようになっています。ですが、半角文字列の折り返しは単語毎に行われるというブラウザの仕様のためか、場合によってはソースコードの折り返しが上手く行われず、横スクロールバーが表示されてしまうという問題があります。そうなると、スクロールした部分は背景の塗り分けが上手く行われず、SSのように違和感のある表示になってしまう、という問題があります。 </p>
<h3>対応策</h3>
<p>上手く折り返し表示させる方法がよく分からなかったので、自分の場合、常に折り返し無しで表示することにしました。そして背景の塗り分け自体も廃し、常時横スクロールバーを表示。また、上のツールメニューもあわせて表示の仕方を変更しました。</p>
<p>長々と言葉で説明しても冗長になるだけなので、SyntaxHighlighterのCSSを上書きするのに使用したCSSファイルを示します。</p>
</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7e26ed98-51b2-44a7-9829-108f934638ab" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="css">.dp-highlighter{
	overflow-y:visible;
	overflow-x:scroll;
	background-color:#fcfcfc;
	width:100%;
}
.dp-highlighter ol li,.dp-highlighter ol li.alt{
	background-color:#fcfcfc;
	white-space:pre;
}
.dp-highlighter ol li, .dp-highlighter .columns div, .dp-highlighter .tools {
	border-left:3px solid #e26c6c;
}
.dp-highlighter .tools{
	font-size:120%;
	height:2em;
	padding:0px;
	background-color:#fcfcfc;
}
.dp-highlighter .tools a{
	font-size:100%;
	display:block;
	color:#888888;
	float:left;
	height:1.5em;
	margin:0px;
	padding-top:0.4em;
	padding-bottom:0.1em;
	padding-left:0.5em;
	padding-right:0.5em;
	background-image:url("images/shToolsBG.png");
}
.dp-highlighter .tools a:hover{
	background-image:none;
	background-color:#ffffff;
}
.dp-highlighter ol.dp-c{
	clear:both;
	background-color:#fcfcfc;
}</pre>
</div>
<p>実際に適用するとこんな感じ。</p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image26.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="175" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb23.png" width="484" border="0" /></a> </p>
<p>スクロールさせても崩れてません。</p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image27.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="165" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb24.png" width="484" border="0" /></a> </p>
<p>今回は不具合修正をきっかけとして既製のライブラリのCSSの上書きに取り組みましたが、今回のツールメニューや左ボーダーの変更のように、単なるデザインの変更にも使えるので、結構ブラックボックス化しがちなライブラリのデザインを、サイトのデザインと調和させる目的でも色々弄ってみてはいかがでしょうか。</p>
<h3>追記</h3>
<p>このCSSは桁の表示には未対応です。まぁ全角文字が含まれているとどうせズレが生じるし、放置で良いかな･･･。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/blog/877/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WPCustomFieldsEditorよもやま噺</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/814/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/814/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 10:07:33 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WPCustomFieldsEditor]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Custom Field]]></category>
		<category><![CDATA[PHPXref]]></category>
		<category><![CDATA[Windows Live Writer]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/814/</guid>
		<description><![CDATA[
このエントリではWPCustomFieldsEditorを製作するにあたって蓄えたトリビア（死語？）紹介をしてみます。後半愚痴だか雑記だかよく分からなくなっていますが。 ん？二度ネタが多い？それは仕様です。
ログイン情 [...]]]></description>
			<content:encoded><![CDATA[</p>
<p>このエントリでは<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/789/">WPCustomFieldsEditor</a>を製作するにあたって蓄えたトリビア（死語？）紹介をしてみます。後半愚痴だか雑記だかよく分からなくなっていますが。 ん？二度ネタが多い？それは仕様です。</p>
<h3>ログイン情報の取得方法</h3>
<p><a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/789/">WPCustomFieldsEditor</a>ではXML-RPCを使ってWordPressを操作しています。WordPressをXML-RPCで操作するには、WordPressのエンドポイントURLとログインするためのユーザー名とパスワードが必要となります。これらは、リフレクションなどを使って、Windows Live Writer（以下WLW）が内部に保持している情報を取得しています。エンドポイントURLはBlogクラスのPostApiUrlプロパティから、ユーザー名とパスワードはXmlRpcBlogClientクラスのUsernameプロパティ、Passwordプロパティからそれぞれ取得できます。これらのクラスのインスタンスの取得方法については、<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/386/">SharpLab. &#8211; 中まで見よう！Windows Live Writer</a>というエントリに書きましたのでそちらを参照してください。</p>
<h3>WP-XML-RPC APIの情報の集め方</h3>
<p>WordPressをXML-RPCで操作していると述べましたが、WordPressにはmetaWeblog APIを拡張したWP-XML-RPC APIがあり、これを使用しています。metaWeblog APIについては<a href="http://www.na.rim.or.jp/~tsupo/program/blogTool/mt_xmlRpc.html#w01">MovableType で使える XML-RPC API</a>というページが詳しいです。WordPressが独自に拡張した部分については<a href="http://codex.wordpress.org/XML-RPC_wp">XML-RPC wp « WordPress Codex</a>に纏まっています。</p>
<p>ただ、これだけでは残念ながらWordPressのXML-RPCについて網羅しきれていません。最近新しく追加された機能などについて調べる場合は<a href="http://lists.automattic.com/mailman/listinfo/wp-xmlrpc">wp-xmlrpc Info Page</a>からMLのアーカイブをさらう必要があります。</p>
<p>それでも良く分からなかったら？幸いWordPressはOSSです。ソースコードを読みましょう。その際、便利なのがこちら、<a href="http://lab.yukei.net/wp-code/nav.html?_functions/index.html">PHPXref 0.7: WordPress (latest release)</a>。PHPXrefというツールで、クロスリファレンス化したWordPressのソースコードが掲載されています。</p>
<h3>WP-XML-RPC APIによるカスタムフィールドの扱い方</h3>
<p><a href="http://comox.textdrive.com/pipermail/wp-xmlrpc/2007-November/000103.html">[wp-xmlrpc] exposing and manipulating custom fields</a>に記述があります。大体分かり易い記述ですが、ちょっと躓くところがあったので記しておきます。以下の部分。</p>
<blockquote><p>If a custom field entry included with a post contains an &quot;id&quot; value then an update is done. If there is no &quot;id&quot; then an add is done. If there is an &quot;id&quot; value and no &quot;key&quot; value then the custom field with that id is deleted.</p>
</blockquote>
<p>「なになに…idがなければ新しいカスタムフィールドとして追加され、idはあってもkeyがなければそのカスタムフィールドは削除されるとな？」と理解し、追加したい場合はidに空文字列を持たせる形で実装を進めたのですが、うんともすんとも動かない。カスタムフィールドを削除しようと思ってkeyに空文字列を渡した場合には空文字列をキーにしたカスタムフィールドが出来てしまうという始末。（管理画面からは空文字列をキーにすることは出来ないのでバグでしょう。）</p>
<p>実はno idという状態とはidの値を空にしろ、という意味ではなく、idというメンバ自体を持たせるな、ということでした。今振り返ってみて素直に読めば確かにその方が読んでいて通りが良いですが、なんだかなー、もーちょっとわかりやすくしてくれよ、と思いました、はい。</p>
<h3>アンダーバーで始まるフィールド</h3>
<p><a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/523/">SharpLab. &#8211; WPCustomFieldsEditor制作中</a>というエントリにも書いたのものですが。</p>
<p>WordPressの管理画面からは見えないのですが、WP-XML-RPC API経由だと_edit_last、_edit_lockや、_encloseme、_pingmeなどの謎のカスタムフィールドが見える場合があります。これらアンダーバーでキー名が始まるカスタムフィールドですが、結局ググってもよくわからなかったので、WPCustomFieldsEditorでは一律無視することにしています。従って、ユーザーがアンダーバーでキー名が始まるカスタムフィールドを作成した場合も巻き添えで無視されてしまうので、運用には十分注意してください。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/814/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WPCustomFieldsEditor</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/789/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/789/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 02:18:23 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WPCustomFieldsEditor]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Custom Field]]></category>
		<category><![CDATA[Windows Live Writer]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/?p=789</guid>
		<description><![CDATA[これは何？
Windows Live WriterにWordPressのカスタムフィールド編集機能を追加するプラグインです。カスタムフィールドはエントリに独自のメタデータを付加したい場合のために確保されたフィールドで、W [...]]]></description>
			<content:encoded><![CDATA[<h3>これは何？</h3>
<p>Windows Live WriterにWordPressのカスタムフィールド編集機能を追加するプラグインです。カスタムフィールドはエントリに独自のメタデータを付加したい場合のために確保されたフィールドで、WordPressをCMSとして多少手の込んだサイト管理に使用する場合には非常に重宝する機能です。このプラグインでは、エントリに付加するカスタムフィールドを、投稿時に編集する機能をWindows Live Writerに提供します。</p>
<h3>ダウンロード</h3>
<p><a href="http://depot.sharplab.net/CSharp/WLWPlugin/WPCustomFieldsEditor.zip">WPCustomFieldsEditor.zip</a></p>
<h3>動作環境</h3>
<ul>
<li>Microsoft Windows XP SP2 以降または Windows Vista（Windows Live Writerに準拠） </li>
<li>Microsoft .NET Framework 2.0以上 </li>
<li>Windows Live Writer Beta（Build14.0.5025.904) </li>
<li>WordPress 2.5以上 </li>
</ul>
<p>※現在、<a href="http://windowslivewriter.spaces.live.com/blog/cns!D85741BB5E0BE8AA!1508.entry">Writer Zone</a>で配布されているTechnical Preview版では、おそらく動作しなくなっています。ご注意ください。</p>
<h3>インストール方法</h3>
<p>ダウンロードしたファイルを展開してsetup.exeを実行してください。</p>
<h3>アンインストール方法</h3>
<p>コントロールパネルのプログラムの追加と削除からWPCustomFieldsEditorを選択し削除してください。</p>
<h3>操作説明</h3>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image15.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="111" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb14.png" width="240" align="left" border="0" /></a> エントリの投稿を行うと、スプラッシュウィンドウに続いてカスタムフィールドの編集画面が現れます。この画面からカスタムフィールドの追加・削除・編集を行うことが出来ます。</p>
<hr class="clear-both" />
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image17.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="219" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb16.png" width="324" border="0" /></a></p>
<h3>更新履歴</h3>
<ul>
<li>2008-10-01 ver.1.03に差し替え。内部動作を変更。</li>
<li>2008-09-20 ver.1.02に差し替え。WLW Beta(Build14.0.5025.904)に対応。 </li>
<li>2008-08-13 Blogシステムの判別ミスがあったのでver.1.01に差し替え </li>
<li>2008-08-13 イニシャルリリース </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/789/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>WPCustomFieldsEditor制作中</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/523/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/523/#comments</comments>
		<pubDate>Sat, 09 Aug 2008 16:45:00 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WPCustomFieldsEditor]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Custom Field]]></category>
		<category><![CDATA[Windows Live Writer]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/523/</guid>
		<description><![CDATA[&#160;
WordPressのカスタムフィールドをWindowsLiveWriterから編集するためのプラグインを製作中。プラグインの形式はpublish notification hooksプラグイン。とりあえずX [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image7.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="216" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb7.png" width="324" border="0" /></a>&#160;</p>
<p>WordPressのカスタムフィールドをWindowsLiveWriterから編集するためのプラグインを製作中。プラグインの形式はpublish notification hooksプラグイン。とりあえずXML-RPCを使って記事に付加されたカスタムフィールドの一覧を取得するところまで漕ぎ着けた。ちなみにXML-RPCでWordPressを操作する際に必要となるID、Passwordには<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/386/">SharpLab. &#8211; 中まで見よう！Windows Live Writer</a>というエントリで紹介した方法を使用してWLWが内部に保持している情報を取得して使っています。エンドポイントURLも確かBlogクラスあたりのメンバにあったのを使用。</p>
<p>さて、ここまででカスタムフィールドの仕様に関して気づいたことが何点か。</p>
<ul>
<li>_edit_last、_edit_lockや、_encloseme、_pingmeなどの謎のカスタムフィールドがWordPressによって勝手に追加されている。アンダーバーが付いているカスタムフィールドはWordPressによって自動的に追加されたもの？ちなみにこれらはWordPressの管理画面からは不可視。 </li>
<li>カスタムフィールドのキーは一意である必要はない。キーとは別にidが振られており、それで管理が行われている。（参考：<a href="http://comox.textdrive.com/pipermail/wp-xmlrpc/2007-November/000103.html">[wp-xmlrpc] exposing and manipulating custom fields</a>） </li>
</ul>
<p>来週暇なんで作業が進むといいなー。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/wpcustomfieldseditor/523/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>publish notification hooksプラグインに関する試行錯誤の続き</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/472/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/472/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 00:23:54 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[publish notification hooks plugin]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/472/</guid>
		<description><![CDATA[ちょっとだけ状況が改善。

「SharpLab. &#8211; publish notification hooksでpost内容を安全に書き換えるには」のコメント欄を受けて、「サーバーに修正後のエントリをアップ、その [...]]]></description>
			<content:encoded><![CDATA[<p>ちょっとだけ状況が改善。</p>
<h4></h4>
<p><a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/433/#comments">「SharpLab. &#8211; publish notification hooksでpost内容を安全に書き換えるには」</a>のコメント欄を受けて、「サーバーに修正後のエントリをアップ、そのアップされたエントリをWLWでDLして再読み込み」という方法を試してみた。</p>
</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:a8e09b35-b132-480a-b76b-b3aebce79e4a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">        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 editingContextFieldInfo = publishingContext.GetType().GetField("_editingContext", BindingFlags.NonPublic | BindingFlags.Instance);
            BlogPostEditingManager manager = (BlogPostEditingManager)editingContextFieldInfo.GetValue(publishingContext);

            PropertyInfo localFilePropertyInfo = manager.GetType().GetProperty("LocalFile", BindingFlags.NonPublic | BindingFlags.Instance);
            PostEditorFile postEditorFile = (PostEditorFile)localFilePropertyInfo.GetValue(manager,null);

            BlogPost blogPost = (BlogPost)publishingContext.PostInfo; ;
            blogPost.Title = "test";
            return true;
        }</pre>
</div>
</p>
<p>このようにOnPrePublishメソッド内では投稿内容の書き換えだけを行って、</p>
</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:57de8073-5d97-493b-8f9e-c50a42c683c0" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">        public override void OnPostPublish(IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

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

            //publishingContextからリフレクションでBlogPostEditingManagerを取得
            FieldInfo editingContextFieldInfo = publishingContext.GetType().GetField("_editingContext", BindingFlags.NonPublic | BindingFlags.Instance);
            BlogPostEditingManager manager = (BlogPostEditingManager)editingContextFieldInfo.GetValue(publishingContext);
            BlogPost blogPost = blog.GetPost(publishingContext.PostInfo.Id, publishingContext.PostInfo.IsPage);
            manager.EditPost(new BlogPostEditingContext(postEditorForm.CurrentBlogId, blogPost));
        }</pre>
</div>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/08/image.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="278" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/08/image-thumb.png" width="324" align="right" border="0" /></a></p>
<p>OnPostPublishメソッド内で記事の再読み込みを行うというやり方でテスト。</p>
<p>YATTA!この場合だと、画像が消えてしまうことなく、書き換え内容を投稿画面に反映することが出来た。だが一方で、「Smart Content」部を選択しても、右のように&quot;Selected item cannot be edited.&quot;というメッセージが出て、編集出来なくなるという問題が。また、画像も良く見てみると、ローカル画像という扱いではなく、Web画像という扱いになってしまっている。つまりこの方法ではWindows Live Writerがローカルに保存した記事についての情報（.wpost拡張子でMy Weblog Posts以下に保存されている奴）を利用出来ていないようだ。なかなか難しいな…。このやり方でのOnPrePublishメソッド部のみ実行し、その後手動でサイドバーのRecently Postedの一覧の中から投稿したエントリを選択するというやり方なら、上手くマージされた状態で読み込め、「Smart Content」部も再編集可能なので、どこかに方法はあるはずだとは思うのだが…。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/472/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>publish notification hooksでpost内容を安全に書き換えるには</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/433/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/433/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 05:37:54 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[publish notification hooks plugin]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/433/</guid>
		<description><![CDATA[追記：やっぱり問題が発生するようです。エントリ内の写真が消えたりする問題が起きるようなので、この方法も駄目でした…orz
ひとつ前のエントリ（中まで知ろう！Windows Live Writer）で、Windows Li [...]]]></description>
			<content:encoded><![CDATA[<p><strong>追記：やっぱり問題が発生するようです。エントリ内の写真が消えたりする問題が起きるようなので、この方法も駄目でした…orz</strong></p>
<p>ひとつ前のエントリ（<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/386/">中まで知ろう！Windows Live Writer</a>）で、Windows Live Writerの、SDKには載っていないクラスを色々と紹介しました。その内容をうけて、このエントリではPublish Notification Hook プラグインで、投稿前に記事内容を書き換える方法を紹介したいと思います。以前にも、<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/276/">SharpLab. &#8211; publish notification hooksでpost内容を書き換えるには</a>というエントリでpublish notification hooksプラグインで投稿内容を書き換える方法を紹介したことがありました。ですが、</p>
<blockquote><p>WLW 自体は書き換えられることを想定してないので、プラグインから書き換えても投稿後にエディタ中の表示は変化しません。</p>
<p>   <cite><a href="http://blogs.wankuma.com/katamari/archive/2008/07/17/149230.aspx">Publish Notification Hook プラグイン 値の書き換え-katamari.wankuma.com</a></cite></p></blockquote>
<p>というJZ5さんの検証エントリの通り、投稿後の画面がおかしくなる問題がありました。<strike>今回の方法ではその回避を図っています。</strike></p>
<p>とりあえずソースコードを示します。</p>
</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:ec3e7675-47fb-4c08-be9e-2a364e15ec33" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:firstline[1]">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;
        }
    }
}
</pre>
</div>
</p>
</p>
<p>細かく見ていきましょう。</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:22a40fd8-3270-42ae-8036-35b381404a7c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:firstline[19]">            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
</pre>
</div>
<p>この行ではPostEditorFormクラスのインスタンスを取得しています。前エントリ参照。</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:91913654-dc8e-475b-836d-d78c32914c5a" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:firstline[20]">           Blog blog = new Blog(postEditorForm.CurrentBlogId);
</pre>
</div>
<p>この行ではBlogクラスのインスタンスを取得しています。前エントリ参照。</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:db396841-d1cd-4d8f-8f88-af89a069c0cf" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:firstline[23]">            FieldInfo fieldInfo = publishingContext.GetType().GetField("_editingContext", BindingFlags.NonPublic | BindingFlags.Instance);
            BlogPostEditingManager manager = (BlogPostEditingManager)fieldInfo.GetValue(publishingContext);
</pre>
</div>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/07/image12.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="137" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/07/image-thumb12.png" width="244" align="right" border="0" /></a>ここでは、BlogPostEditingManagerクラスのインスタンスを取得してます。OnPrePublishメソッドの引数として渡されたpublishingContextにはBlogPostHtmlEditorクラス（WindowsLive.Writer.PostEditor.PostHtmlEditing名前空間に所属）のインスタンスが格納されており、その_editingContextというパブリックでないフィールドにBlogPostEditingManagerが格納されています。BlogPostHtmlEditorクラス自体もパブリックなクラスではないので、ここではリフレクションで取得しています。なお、BlogPostEditingManagerクラスはエントリを編集画面に読み込んだり、削除したりできるクラスです。正直、自分も良く分かっていません(笑)。</p>
<p>&#160;</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7200da68-c62c-417e-90b4-fd9c7babfefb" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:firstline[25]">            BlogPost blogPost = (BlogPost)publishingContext.PostInfo;
</pre>
</div>
<p>ここでは編集対象のエントリを表すBlogPostクラスのインスタンスを取得しています。前エントリ参照。</p>
</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:15ea5581-4199-4550-84c6-cebfb25f5394" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="css:firstline[27]">            blogPost.Title = "test";//エントリ内容への操作
</pre>
</div>
<p>エントリ内容への書き換えをここで行うことが出来ます。この例ではタイトルの書き換えをしています。試したわけではありませんが、カテゴリや概要に対して変更を加えることもできる筈です。</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:20df1aaf-6cae-4c5e-aa6f-f6907cbdcffa" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#:firstline[29]">            manager.EditPost(new BlogPostEditingContext(postEditorForm.CurrentBlogId, blogPost));
</pre>
</div>
<p>そして、書き換えた後の大事な後始末、書き換えたエントリのPostEditorEormへの再読み込みをここで行っております。BlogPostEditingManagerクラスのEditPostメソッドに、それっぽい引数を与えて呼び出せば読み込んでくれるようです。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/433/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>中まで見よう！Windows Live Writer</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/386/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/386/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 17:23:28 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[publish notification hooks plugin]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/386/</guid>
		<description><![CDATA[WYSIWYG編集が可能で、Wordを扱うかのような感覚でBlogをサクサク書くことが出来るMS謹製投稿クライアントWindows Live Writer。本体だけでも相当強力なソフトですが、機能強化のための各種プラグイ [...]]]></description>
			<content:encoded><![CDATA[<p>WYSIWYG編集が可能で、Wordを扱うかのような感覚でBlogをサクサク書くことが出来るMS謹製投稿クライアントWindows Live Writer。本体だけでも相当強力なソフトですが、機能強化のための各種プラグインを開発することもできるようになっており、.NETをかじっている自分にはなかなか興味をそそられるソフトでもあります。その開発の仕方はJZ5さんこと、松江祐輔さんが書かれた<a href="http://gihyo.jp/dev/serial/01/wl-sdk/0007">使ってみよう！ Windows Live SDK/API：第7回 Windows Live Writer … 技術評論社</a>という記事がチュートリアルとしてとても分かり易いものとなっています。詳しいリファレンスとしては<a href="http://msdn.microsoft.com/en-us/library/aa738906.aspx">Windows Live Writer SDK</a>が現在の正式版に対応する公式で、<a href="http://writerdevzone.spaces.live.com/blog/cns!FF912D98C958E9D3!170.entry">Writer DevZone: Technical Preview: Now Available for Download</a>にこの前出たTecnology Preview版のSDKが転がっています。どっちも英語ですけど。</p>
<p>で、このエントリでは、ここ数日オブジェクトブラウザを通じてWindows Live WriterのDLL群とにらめっこした結果わかった、SDKに載っていない本体の内部構造の話をしてみようかと。Windows Live Writerの中にどんなクラスがあるかや、どうやってそのインスタンスをプラグイン側から取得するかのお話。</p>
<h3>Windows Live WriterのメインFormの取得方法</h3>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/07/image10.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="148" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/07/image-thumb10.png" width="244" align="right" border="0" /></a> 何はなくとも、記事編集画面が無ければ始まらない。Windows Live Writerの記事編集画面のFormのインスタンスをプラグインから取得する方法から説明を始めます。プラグインが呼び出された時に呼ばれるメソッドのうちいくつかは、dialogOwnerという、System.Windows.Forms.IWin32Window型の引数を持っています。このdialogOwnerという引数が今回のカギとなります。読んでの通り、dialogOwnerは親Formを示しており、SmartContentSource.CreateContentメソッドなら、記事編集画面のForm、PublishNotificationHook.OnPrePublishメソッドやOnPostPublishメソッドなら投稿中のプログレス表示を行うFormとなります。</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:72992a42-2c14-4743-bd79-fc0502fcfd89" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">        private PostEditorForm getPostEditorForm(IWin32Window postProgressForm) {
            return (PostEditorForm)((Form)Form.FromHandle(postProgressForm.Handle)).Owner;
        }</pre>
</div>
</p>
</p>
</p>
<p>PublishNotificationHookの方から取得できるdialogOwnerからメインFormのインスタンスを取得したいならば、上記のようなメソッドを用意して取得すればOK。見ての通り、メインFormのクラス名はPostEditorFormで、WindowsLive.Writer.PostEditor名前空間に所属しているクラスです。今後は記事編集画面のFormのことはPostEditorFormと呼ぶことにします。</p>
<h3>Blogクラスのインスタンスの取得</h3>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/07/image93.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="225" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/07/image9-thumb2.png" width="166" align="right" border="0" /></a>さて、前の項で取得できたPostEditorFormクラスには、CurrentBlogIdというプロパティがあります。このプロパティには、Windows Live Writerで管理しているBlogを識別するためのGUIDが入っており、これを基に現在編集対象としているBlogを表すBlogクラスのインスタンスを取得可能です。こんな感じに。↓</p>
</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b45bfdf2-42d5-454c-b355-b16c79509563" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">            Blog blog = new Blog(postEditorForm.CurrentBlogId);
</pre>
</div>
<p>BlogクラスはWindowsLive.Writer.BlogClient名前空間に所属しているクラスで、メンバには記事の取得や投稿に関するメソッドなど、Blogに関する様々な操作を実現するメソッドやプロパティが含まれています。Blogクラスをオブジェクトブラウザで表示したもののSSを示しましたが、サイズの関係でSSに写っていないものもたくさんあるので、是非自分で確かめてみてください。</p>
<h3>BlogClientクラスのインスタンスの取得</h3>
<p>ところでBlogクラスには、パブリックではないプロパティとしてBlogClientというプロパティがあります。このプロパティには、IBlogClient（WindowsLive.Writer.Extensibility.BlogClient名前空間に所属）というインターフェイスを実装したクラスのインスタンスが含まれています。一例を挙げると、WordPressClientクラスや、MovableTypeClientクラス、WindowsLiveSpacesClientクラス（全てWindowsLive.Writer.BlogClient.Clients名前空間に所属）などです。これらにはUsernameや、Passwordというプロパティが含まれており、自前でXML-RPCを使ってサーバーとやり取りしたい場合などに活用できます。（WordPressはMetaWeblobAPIの拡張に熱心であるので、Windows Live Writerが対応していない機能もあり、意外と使いたくなる場面があるものです）</p>
<h3>publishingContext.PostInfoの実体</h3>
<p>PublishNotificationHook.OnPrePublishメソッドやOnPostPublishメソッドのpublishingContextという引数には、PostInfoというIPostInfo型のプロパティがあるのは御存知だと思います。以前自分はこのプロパティに格納されているインスタンスの、IPostInfoインターフェイスでは読み取り専用になっているプロパティに対してリフレクションで値をセットするコードがなぜ動くのかが分からないとか<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/276/">ぼやいていました</a>。</p>
<p>調べてみたところ、リフレクションでアクセスするのは、参照するのに使われたインターフェイスのメンバではなく、インスタンスのメンバだから、ということのようです。用語法をあまり理解できていないので、おかしな説明になっているかもしれません。要するに、PostInfoに対してリフレクションでアクセスできるのは、IPostInfoインターフェイスのメンバだけではなく、BlogPostクラスのメンバなのだ、ということです。これなら前のエントリのpi.CanWriteの部分がtrueを返すのも納得できます。 </p>
<p>まぁとりあえずpublishingContext.PostInfoにはBlogPostクラスのインスタンスが入っているということです。そこで、こんな感じにキャストしてやると、</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:abb1c14e-3e29-4d3b-b537-1f1c7fd7f43c" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">            BlogPost blogPost = (BlogPost)publishingContext.PostInfo;
</pre>
</div>
<p>よりエントリの情報を詳細に得ることができるようになります。投稿スラッグや概要（Excerpt）、投稿日時を表すっぽいプロパティもあるので、チェックしてみてはいかがでしょうか。</p>
<p>次のエントリでは、これらを利用して、Publish Notification Hook プラグインで、投稿前に記事内容を書き換える方法を紹介したいと思います。プラグインからの書き換え後、エディタ中の表示が変化しない問題を解決するために、エントリを管理しているクラスの説明も少しだけします。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/386/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WLW編集画面のHTMLDocumentを安全に書き換えるには</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/367/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/367/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 16:17:26 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/367/</guid>
		<description><![CDATA[前のエントリでは
表示モードを「HTMLコード」としていた場合、HTMLDocumentに対してプラグインから操作後に表示モードを「標準」に戻すと、HTMLDocumentに対する操作内容が飛んでしまう

という問題で躓 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/251/">前のエントリ</a>では</p>
<blockquote><p>表示モードを「HTMLコード」としていた場合、HTMLDocumentに対してプラグインから操作後に表示モードを「標準」に戻すと、HTMLDocumentに対する操作内容が飛んでしまう</p>
</blockquote>
<p>という問題で躓いていたが、HTMLDocumentに対して操作を行う前に表示モードを「標準」にしておくことで対処できた。</p>
<p>こんな感じ。HTMLDocumentを直接操作できるようになって、うはー 夢が広がりんぐ</p>
<p>なお、表示モードの切り替えがタブ式になったTechnology Preview版限定。</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:e54cfa12-a815-4601-a0f7-009cb1e669a6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">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);

            WindowsLive.Writer.Controls.MiniTabsControl MiniTabsControl = (WindowsLive.Writer.Controls.MiniTabsControl)findControlByName(postEditorForm, "MiniTabsControl", "WindowsLive.Writer.Controls");
            MiniTabsControl.SelectTab(0);

            WriterMshtml.MshtmlEditor mshtmlEditor = (WriterMshtml.MshtmlEditor)findControlByName(postEditorForm, "MshtmlEditor", "WindowsLive.Writer.Mshtml");
            mshtml.IHTMLDocument2 doc = mshtmlEditor.HTMLDocument;
            //あとは煮るなり焼くなり。
        }

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

        private Control findControlByName(Control control, string controlName, string controlNamespace) {

            foreach (Control cChild in control.Controls) {

                Type t = cChild.GetType();

                if (t.Name == controlName &amp;&amp; t.Namespace == controlNamespace) {
                    return cChild;
                }

                if (cChild.HasChildren) {
                    Control returned = findControlByName(cChild, controlName, controlNamespace);
                    if (returned != null) {
                        return returned;
                    }
                }
            }

            return null;
        }
    }
}</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/367/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPressとXML-RPC API絡みの話。</title>
		<link>http://blog.sharplab.net/computer/blog/299/</link>
		<comments>http://blog.sharplab.net/computer/blog/299/#comments</comments>
		<pubDate>Sat, 19 Jul 2008 14:46:37 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[Custom Field]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[XML-RPC]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/blog/299/</guid>
		<description><![CDATA[WordPress 2.6を新規インストールした場合、XML-RPC API経由での投稿機能は、デフォルトでは無効になるようになったらしい。ver.2.6以前からのアップデートの場合は有効のまま。新規インストールしたWo [...]]]></description>
			<content:encoded><![CDATA[<p>WordPress 2.6を新規インストールした場合、XML-RPC API経由での投稿機能は、デフォルトでは無効になるようになったらしい。ver.2.6以前からのアップデートの場合は有効のまま。新規インストールしたWordPressにWindows Live Writerなどの投稿クライアントを組み合わせて運用することを考えている場合は注意しましょう。XML-RPC APIの有効化は管理画面の「設定」→「投稿設定」から。以下は情報元からの引用。</p>
<blockquote><p>XML-RPC is disabled by default for new installs of WordPress. Upgrading will <b>NOT</b> disable XML-RPC (ticket <a href="http://trac.wordpress.org/ticket/7157">7157</a>)</p>
<p><cite><a href="http://joseph.randomnetworks.com/archives/2008/07/14/wordpress-26-xml-rpc-atompub-changes/">WordPress 2.6 &#8211; XML-RPC &amp; AtomPub Changes &#8211; Joseph Scott’s Blog</a></cite></p>
</blockquote>
<p>このエントリには他にもXML-RPC APIのver.2.51からの変更点（ページテンプレートの取得、Blogオプションの取得/設定が出来るようになった、等）が列挙されているので、このエントリは一見の価値有り。</p>
<p>また、このBlogにはこんな記事もあった。</p>
<blockquote><p>Custom fields for posts and pages are now exposed and manageable from metaWeblog.getPost/newPost/editPost, wp.getPage/newPage/editPage via the custom_fields field. I was really happy to get this in, I think there is a lot of potential in being able to manage custom fields externally.</p>
<p><cite><a href="http://joseph.randomnetworks.com/archives/2008/03/29/wordpresss-25/">WordPresss 2.5 &#8211; Joseph Scott’s Blog</a></cite></p>
</blockquote>
<p>WordPress 2.5からはカスタムフィールドのデータをXML-RPC APIから扱えるようになっていたらしい。知らんかった。憶えておこう。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/blog/299/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WordPress 2.6のリビジョン管理機能とWindowsLiveWriter</title>
		<link>http://blog.sharplab.net/computer/blog/295/</link>
		<comments>http://blog.sharplab.net/computer/blog/295/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 13:56:30 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[Revision]]></category>
		<category><![CDATA[Windows Live Writer]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/blog/295/</guid>
		<description><![CDATA[WordPress 2.6の注目の新機能のひとつ、エントリのリビジョン管理機能、WordPress 2.6を入れたついでに早速試してみた。
 
こんな感じに比較が出来る。うん、良い感じ。
次に、WindowsLiveWr [...]]]></description>
			<content:encoded><![CDATA[<p>WordPress 2.6の注目の新機能のひとつ、エントリのリビジョン管理機能、WordPress 2.6を入れたついでに早速試してみた。</p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/07/image3.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="191" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/07/image-thumb3.png" width="484" border="0" /></a> </p>
<p>こんな感じに比較が出来る。うん、良い感じ。</p>
<p>次に、WindowsLiveWriterを使用して投稿をした場合を試してみた。</p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/07/image4.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="116" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/07/image-thumb4.png" width="484" border="0" /></a> </p>
<p>これもうまくいく。</p>
<p>だが、WordPressの投稿フォームとWindowsLiveWriterを併用して編集した場合はうまく比較が行われない。</p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/07/image5.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="495" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/07/image-thumb5.png" width="484" border="0" /></a> </p>
<p>WordPressで編集した版はpタグで括られた段落毎にブロックに分けられているのだが、WLWで編集した版は全体が一つのブロックとして纏められてしまっており、それが原因で比較に失敗しているようだ。</p>
<p>一人でBlogを書く際には過去の版に戻す位しかリビジョン管理機能を使うことはないだろうから、あまり影響はないだろうけど、ビジネスブログなどで複数人で記事を推敲する場合はリビジョン比較機能を使う場面も出てくるだろう。そういう場合は投稿クライアントを使うか使わないか統一した方がよさそうだ。（まぁ大した問題じゃないが…。）</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/blog/295/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>publish notification hooksでpost内容を書き換えるには</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/276/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/276/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 15:57:40 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[publish notification hooks plugin]]></category>
		<category><![CDATA[Windows Live Writer]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/276/</guid>
		<description><![CDATA[以前SharpLab. &#8211; publish notification hooksではpost内容を書き換えられないというエントリをあげた。その時JZ5さんからMSにフィードバックを送りましょう、というコメント [...]]]></description>
			<content:encoded><![CDATA[<p>以前<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/216/">SharpLab. &#8211; publish notification hooksではpost内容を書き換えられない</a>というエントリをあげた。その時JZ5さんからMSにフィードバックを送りましょう、というコメントを頂いたので、実際に<a href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=994&amp;SiteID=1">Windows Live Writer Developer Forums</a>で提起してみたところ、Scøttさんから自エントリの紹介という形でpost内容を書き換えるためのTipsを紹介頂いた。なるほどフィードバックは送ってみるものだ。</p>
<p>さて、その紹介頂いた<a href="http://scottisafooldev.spaces.live.com/blog/cns!FE151030F50B5B37!993.entry">InsertableContentSource: New Writer Plugins Using The New SDK</a>というエントリは、CTP版の新SDKを使って作られたプラグインを紹介するエントリなのだが、その中で参考になるのは「ScottIsAFool.WriterUtilities」というセクション。エントリの中で紹介されているプラグインを実装するのに使われた、エントリ内容書き換え用のユーティリティクラス（WriterUtilsクラス）の使い方を紹介している。このクラスのソースコードも<a href="http://www.codeplex.com/NewLiveWriterPlugins">CodePlexにあげられていた</a>ので、以下に抜粋して引用する。</p>
</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:eb7a07ab-055f-4596-97ca-e914d752b338" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">namespace ScottIsAFool
{
    public static class WriterUtils
    {
        public static bool ReplaceText(IPostInfo postInfo, string value, PostItems item)
        {
            PropertyInfo[] propInfos = postInfo.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (PropertyInfo pi in propInfos)
            {
                if (pi.Name == item.ToString() &amp;&amp; pi.CanWrite)
                {
                    pi.SetValue(postInfo, value, null);
                    return true;
                }
            }
            return false;
        }
    }
}</pre>
</div>
<p><cite><a href="http://www.codeplex.com/NewLiveWriterPlugins">New Live Writer Plugins (SDK: 1.1)</a> </cite></p>
</p>
<p>…何と反応していいのか分からない素敵なnamespace名は措いておくとして。<br />
  <br />要するに渡されたIPostInfo型の引数に対して、リフレクションで無理矢理プロパティに値をセットしているようだ。しかし、リフレクションについてよくわかっていないのだが、何で読み取り専用プロパティであるIPostInfoのメンバに値をセットするようなことが出来るのだろう？読み取り専用プロパティである限り、pi.CanWriteの部分は常にfalseを返すのではないのか？ようわからん。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/276/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WLW編集画面のHTMLDocumentを操作する上での障害</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/251/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/251/#comments</comments>
		<pubDate>Sat, 21 Jun 2008 06:23:12 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[InvalidSourceModifier]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/251/</guid>
		<description><![CDATA[このまえ「Windows Live WriterプラグインからエントリのHTMLDocumentを取得する方法」というエントリでWLW編集画面のHTMLDocumentオブジェクトを取得する方法を紹介したけれども、その方 [...]]]></description>
			<content:encoded><![CDATA[<p>このまえ「<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/217/">Windows Live WriterプラグインからエントリのHTMLDocumentを取得する方法</a>」というエントリでWLW編集画面のHTMLDocumentオブジェクトを取得する方法を紹介したけれども、その方法にはまだ解決できていない問題があり、今回は自分がどこで躓いているのかを説明しつつ嘆くエントリ(笑)。</p>
<p>さて、現在のInvalidSourceModifierは以下のようなソースになっている。</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:df7a0bf0-3fe8-421c-b631-0f38269a3a81" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">extern alias MicrosoftMshtml;
extern alias WriterInteropMshtml;

using System;
using WindowsLive.Writer.Api;
using System.Windows.Forms;
using MicrosoftMshtml.mshtml;
using WindowsLive.Writer.PostEditor;

using WriterMshtml = WindowsLive.Writer.Mshtml;

namespace InvalidSourceModifier {
    //TODO:ImagePathの設定！
    [WriterPlugin("9388e56b-c684-4e04-b7f6-b8cc224d70b2", "InvalidSourceModifier", PublisherUrl = "http://www.sharplab.net/")]
    public class InvalidSourceModifier : PublishNotificationHook {
        public override bool OnPrePublish(System.Windows.Forms.IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
            WriterMshtml.MshtmlControl mshtmlControl = (WriterMshtml.MshtmlControl)findControlByName(postEditorForm, "MshtmlControl", "WindowsLive.Writer.Mshtml");

            IHTMLDocument3 doc = (IHTMLDocument3)mshtmlControl.HTMLDocument;

            IHTMLElementCollection allElement = doc.getElementsByTagName("*");
            foreach (IHTMLElement elem in allElement) {
                object align = elem.getAttribute("align", 0);
                object border = elem.getAttribute("border", 0);
                if (!(align == null || align is DBNull)) {
                    elem.removeAttribute("align", 0);
                    elem.style.styleFloat = (string)align;
                }
                if (!(border == null || border is DBNull)) {
                    elem.removeAttribute("border", 0);
                    elem.style.borderWidth = (string)border;
                }
            }

            updateTextEditorControl(postEditorForm);

            return true;
        }

        private void updateTextEditorControl(PostEditorForm postEditorForm) {

            WriterMshtml.MshtmlEditor mshtmlEditor = (WriterMshtml.MshtmlEditor)findControlByName(postEditorForm, "MshtmlEditor", "WindowsLive.Writer.Mshtml");
            mshtmlEditor.Focus();

            Control test = findControlByName(postEditorForm, "PostEditorMainControl", "WindowsLive.Writer.PostEditor");

        }

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

        private Control findControlByName(Control control, string controlName, string controlNamespace) {

            foreach (Control cChild in control.Controls) {

                Type t = cChild.GetType();

                if (t.Name == controlName &amp;&amp; t.Namespace == controlNamespace) {
                    return cChild;
                }

                if (cChild.HasChildren) {
                    Control returned = findControlByName(cChild, controlName, controlNamespace);
                    if (returned != null) {
                        return returned;
                    }
                }
            }

            return null;
        }

    }

}</pre>
</div>
<p>まず、getPostEditorFormメソッドで投稿の進捗状況を表すプログレスバーを載せたFormを基に、親のPostEditorFormを取得、その後、findControlByNameメソッドを使い、PostEditorForm内から、nameとnamespaceを頼りにMshtmlControlコントロールを探し、そのHTMLDocumentプロパティから取得する、というやり方。</p>
<p>これでめでたく「標準」モードや、「Webプレビュー」モードのHTMLDocumentオブジェクトが習得できるのだけれども、HTMLDocumentオブジェクトに対して操作を加えると、「HTMLコード」画面での内容と、HTMLDocumentの不整合が起きてしまう。特に、表示モードを「HTMLコード」としていた場合、HTMLDocumentに対してプラグインから操作後に表示モードを「標準」に戻すと、HTMLDocumentに対する操作内容が飛んでしまう。</p>
<p>む～。なんとかならんものか。誰か知恵をお貸しくださいませ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/251/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Windows Live WriterプラグインからエントリのHTMLDocumentを取得する方法</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/217/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/217/#comments</comments>
		<pubDate>Sun, 15 Jun 2008 07:21:00 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/217/</guid>
		<description><![CDATA[&#160;publish notification hooksではpost内容を書き換えられないという前回のエントリに対して、ＪＺ５さんからFeedBackを送りましょう、という指摘があったので実際にWindows L [...]]]></description>
			<content:encoded><![CDATA[<p>&#160;<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/216/">publish notification hooksではpost内容を書き換えられない</a>という前回のエントリに対して、<a href="http://katamari.jp">ＪＺ５</a>さんからFeedBackを送りましょう、という指摘があったので実際に<a href="http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=994&amp;SiteID=1">Windows Live Writer: Development &#8211; MSDN Forums</a>に送りに行ってみると、<a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2746811&amp;SiteID=1">Solution: How to get an HTMLDocument object for the main post body from your plugin &#8211; MSDN Forums</a>という素敵なスレッドが。エントリのIHTMLDocument2オブジェクトを返してくれる_FindTridentFromControlメソッドと、それを呼び出すための_FindTridentFromLWParentというメソッドのコードスニペットが公開されている。_FindTridentFromLWParentメソッドは、SmartContentSource.CreateContentメソッドなどで渡される、System.Windows.Forms.IWin32Window型のdialogOwnerという引数を渡して呼び出せば良い。実際にSmartContentSourceプラグインの中で試用してみると、確かにIHTMLDocument2オブジェクトが取得できた。これは便利。</p>
<p>一方、publish notification hooksプラグインの中で、OnPrePublishメソッドに渡されるdialogOwnerを使ってFindTridentFromLWParentメソッドを呼び出す場合は工夫が必要。OnPrePublishメソッドで渡されるdialogOwnerは、Live Writerのメインウィンドウではなく、投稿中に表示されるプログレスウィンドウなので、_FindTridentFromLWParentメソッドの代わりに、</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:074ad4c0-862f-4397-9627-ca6ffca0c312" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">        private IHTMLDocument2 _FindTridentFromProgressForm(IWin32Window progressForm) {
            Form writerMainForm = ((Form)Form.FromHandle(progressForm.Handle)).Owner;
            return _FindTridentFromControl(writerMainForm);
        }</pre>
</div>
<p>以上のようなメソッドを作って、FindTridentFromControlメソッドを呼び出す必要がある。</p>
<p>これまでWindowsLive.Writer.Api.IPostInfo.Contentsプロパティに収められている投稿内容を正規表現で書き換えようとしてきたのだが、IHTMLDocument2オブジェクトが扱えるならば、ずっとスマートに色々なことが出来るようになりそうだ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/217/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>publish notification hooksではpost内容を書き換えられない</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/216/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/216/#comments</comments>
		<pubDate>Sat, 14 Jun 2008 15:27:54 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[InvalidSourceModifier]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/216/</guid>
		<description><![CDATA[自分の間抜けさに笑える。
publish notification hooksを使ったプラグインを作ってみようということで、LiveWriterの出力するソースを投稿時に書き換えるプラグイン（InvalidSourceM [...]]]></description>
			<content:encoded><![CDATA[<p>自分の間抜けさに笑える。</p>
<blockquote><p>publish notification hooksを使ったプラグインを作ってみようということで、LiveWriterの出力するソースを投稿時に書き換えるプラグイン（InvalidSourceModifier）をつくることにした。</p>
</blockquote>
<p>とか<a href="http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/199/">言って</a>実際に作っていたのだけれども、いざ形になってきてコンパイルしてみると、</p>
<blockquote><p>エラー&#160;&#160;&#160; 1&#160;&#160;&#160; プロパティまたはインデクサ &#8216;WindowsLive.Writer.Api.IPostInfo.Contents&#8217; は読み取り専用なので、割り当てることはできません。</p>
</blockquote>
<p>というオチ。OnPrePublishメソッドをオーバーライドすれば投稿前にコンテンツの中身を書き換えられるという訳じゃなかったんかい！勘違いでした…。</p>
</p>
<p>&#160;</p>
<p>どーするかなー。後はhookする対象をOnPostPublishメソッドに変更したうえで、投稿後直ぐXML-RPCで直接WordPress上のコンテンツを書きかえる位しかやりようがないかな･･･。つうかそれならWordPressのプラグインをPHPで書いた方が早いか(笑)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/216/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>publish notification hooks</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/199/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/199/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 16:01:15 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[InvalidSourceModifier]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/199/</guid>
		<description><![CDATA[publish notification hooksを使ったプラグインを作ってみようということで、LiveWriterの出力するソースを投稿時に書き換えるプラグイン（InvalidSourceModifier）をつくるこ [...]]]></description>
			<content:encoded><![CDATA[<p>publish notification hooksを使ったプラグインを作ってみようということで、LiveWriterの出力するソースを投稿時に書き換えるプラグイン（InvalidSourceModifier）をつくることにした。</p>
<div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:61748bad-1671-464c-a4d8-e74482f9830e" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
<pre name="code" class="c#">using System;
using System.Collections.Generic;
using System.Text;
using WindowsLive.Writer.Api;

namespace InvalidSourceModifier {
    //TODO:ImagePathの設定！
    [WriterPlugin("9388e56b-c684-4e04-b7f6-b8cc224d70b2", "InvalidSourceModifier", PublisherUrl = "http://www.sharplab.net/")]
    public class InvalidSourceModifier : PublishNotificationHook {
        public override bool OnPrePublish(System.Windows.Forms.IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {
            //publishingContext.PostInfo.Contents
            System.Windows.Forms.MessageBox.Show("test");
           return true;
        }
    }
}</pre>
</div>
<p>…まだこれだけだけど。</p>
<p>さて、実際にコンパイルしてLiveWriterに登録してみると、SDKに付属していたNew SDK Features.docの以下の記述通り、</p>
<blockquote>
<p>Unlike content source plugins, publish notification hooks can be enabled or disabled by the user on a per-blog basis. The first time a publish operation occurs for a particular blog since a publish notification hook was installed, the user will be asked if the hook should be enabled or disabled for that blog.</p>
<p>New SDK Features.doc</p>
</blockquote>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/06/image1.png" rel="lightbox"><img title="image" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="228" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/06/image-thumb.png" width="244" align="left" border="0" /></a>Blog別にプラグインの有効/無効が管理されているのが確認できた。上手く出来てるなー。ちょっとしたことだけど、これは便利だ。</p>
<p>&#160; </p>
<p><a href="http://blog.sharplab.net/wp-content/uploads/2008/06/image2.png" rel="lightbox">&#160;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/invalidsourcemodifier/199/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>WLW CTP インストールしてみた。</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/194/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/194/#comments</comments>
		<pubDate>Sun, 08 Jun 2008 17:04:34 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/194/</guid>
		<description><![CDATA[
Windows Live Writer Technical Preview をインストールしてみた。UIなどをちょくちょく改良されている。でも生成されるソースは相変わらず綺麗じゃないなー。様々なBlogサービスに対応す [...]]]></description>
			<content:encoded><![CDATA[<p><img title="image" height="222" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/06/image4.png" width="350" align="right" border="0" /></p>
<p>Windows Live Writer Technical Preview をインストールしてみた。UIなどをちょくちょく改良されている。でも生成されるソースは相変わらず綺麗じゃないなー。様々なBlogサービスに対応するためとはいえ、もう少しなんとかならないのか。トリミングは便利そうだ。でも英語ではTrimではなくcropという語を使うんだね…。Trimは文字列を切り詰める場合などに限られるのかな？</p>
<p>さぁて、publish notification hooksを使ったプラグインを作ってみるか。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/194/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Live Writer CTP</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/180/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/180/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 13:52:57 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/180/</guid>
		<description><![CDATA[もう一本Windows Live Writerネタ。Windows Live Writer CTPが公開されたそうな。画像のトリミング、センタリングのサポート、エフェクトの強化が中心の模様。詳しいことはkatamari. [...]]]></description>
			<content:encoded><![CDATA[<p>もう一本Windows Live Writerネタ。Windows Live Writer CTPが公開されたそうな。画像のトリミング、センタリングのサポート、エフェクトの強化が中心の模様。詳しいことは<a href="http://blogs.wankuma.com/katamari/">katamari.wankuma.com</a>さんとこの、<a href="http://blogs.wankuma.com/katamari/archive/2008/06/03/141281.aspx">Windows Live Writer Technical Preview</a>というエントリを参照。</p>
<p>また、Windows Live Writer SDKもver.1.1に。ヘッダ・フッタを付加するプラグインが出たそうだけれども、WordPressを使っている自分にはあまり関係がなさそうか。投稿の前後に起動させられるプラグインは色々使い道がありそうだ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/180/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>読める、読めるぞ！！</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/179/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/179/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 13:12:47 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/179/</guid>
		<description><![CDATA[WindowsLiveWriterのSmart Content Sourceプラグインの実装方法を解説したMSDNのドキュメントを大体読了。IEの拡張の作成方法を読むために骨を折った昔のことを思うと万感胸に迫るものがある [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="lightbox" href="http://blog.sharplab.net/wp-content/uploads/2008/06/ts370282.jpg"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="TS370282" src="http://blog.sharplab.net/wp-content/uploads/2008/06/ts370282-thumb.jpg" width="244" align="right" border="0" /></a>WindowsLiveWriterの<a href="http://msdn.microsoft.com/en-us/library/aa738863.aspx">Smart Content Sourceプラグインの実装方法を解説したMSDNのドキュメント</a>を大体読了。IEの拡張の作成方法を読むために骨を折った昔のことを思うと万感胸に迫るものがある。このようにすらすら読めるようになるとは&#8230;。日本語ドキュメントなしでツールバーを作ってしまう人を見て昔は訝しがっていたものだが、ある程度英語力をつければ読めるようになるものなのだな&#8230;。（でもTOEFLはダメだったけどなッ！）</p>
<p>さて読んでいて気づいた機能として、<a href="http://msdn.microsoft.com/en-us/library/aa738928.aspx">HtmlScreenCapture Class</a>を使ったSSの取得機能と、<a href="http://msdn.microsoft.com/en-us/library/aa738877.aspx">Making Content Resizable</a>で解説されているSmart Contentにリサイズ機能がある。この二つの機能は<a href="http://gihyo.jp/dev/serial/01/wl-sdk/0008">gihyo.jpでの記事</a>で紹介されていないので、目を通しておくとよいかと思われる。ちなみに、<a href="http://msdn.microsoft.com/en-us/library/aa738928.aspx">HtmlScreenCapture Class</a>については、タイトルからは想像が行かないが、<a href="http://msdn.microsoft.com/en-us/library/aa738918.aspx">Embedding a Media Player</a>というドキュメントの中で活用法が紹介されている。</p>
<p> さて、ここまでエントリを書きあげたところで気づいたのだが、</p>
<p><a href="http://www.itmedia.co.jp/news/articles/0806/03/news102.html">「Windows Live」APIのマニュアルを日本語化-ITmedia News</a></p>
<p>というニュースが。なんですとー！？折角英語で読んだのに、丁度今日翻訳記事が公開されたそうな。何だったんだ自分の努力は&#8230;。</p>
<p>追記：   <br />と思いきやLive Writer APIのドキュメントは翻訳されていなかった。良かった良か&#8230;ねえよ。どうせなら翻訳してほしいものだ。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/179/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows Live WriterのAPI</title>
		<link>http://blog.sharplab.net/computer/cprograming/windowslivewriter/167/</link>
		<comments>http://blog.sharplab.net/computer/cprograming/windowslivewriter/167/#comments</comments>
		<pubDate>Tue, 27 May 2008 16:15:53 +0000</pubDate>
		<dc:creator>shiroica</dc:creator>
				<category><![CDATA[WindowsLiveWriter]]></category>

		<guid isPermaLink="false">http://blog.sharplab.net/computer/cprograming/windowslivewriter/167/</guid>
		<description><![CDATA[gihyo.jpにWindowsLiveWriterのプラグイン作成方法の解説記事の第二弾が上がっています。著者は松江祐輔さん。あとこっちに補足が。
結構簡単そうだなー。IEのツールバーをC#で作るよりはずっと。Cont [...]]]></description>
			<content:encoded><![CDATA[<p>gihyo.jpに<a href="http://gihyo.jp/dev/serial/01/wl-sdk/0008">WindowsLiveWriterのプラグイン作成方法の解説記事</a>の第二弾が上がっています。著者は松江祐輔さん。あと<a href="http://blogs.wankuma.com/katamari/archive/2008/05/28/139721.aspx">こっちに補足</a>が。</p>
<p>結構簡単そうだなー。IEのツールバーをC#で作るよりはずっと。Content Source Plugin APIというものを使えばいいらしい。@itにGoogle Deskbarのマネージドプラグインを作成する方法の記事があったけど、それと同じ感覚で出来そう。このBlogもWordPress+WindowsLiveWriterで運用しているし、今度試してみよう。</p>
<p>ところでこの記事はContent Source Plugin APIを利用したプラグインについての解説だけれども、WLWには他にも<a href="http://msdn.microsoft.com/en-us/library/aa738851.aspx">Windows Live Writer Application API</a>や、<a href="http://msdn.microsoft.com/en-us/library/bb463266.aspx">Windows Live Writer Provider Customization API</a>というAPIも用意されているらしい。その機能はリンク先のMSDNによれば、以下の通り。</p>
<blockquote><p>Windows Live Writer includes an application API that external applications can use to launch Writer in order to create new posts, to open existing posts, and to support &quot;Blog This&quot; operations for various content types including links, snippets, images, and feed items.</p>
</blockquote>
<p>application APIは外部プログラムから記事を投稿したり編集したり、&quot;Blog This&quot; operations？なるものをサポートするためにWLWを使用するためのAPIということか。Windows Live ToolbarはIEで表示中のページから引用文として取り込みながらWLWを立ち上げられると聞くが、このAPIを使用しているのだろう。</p>
<blockquote><p>Beta Two of Windows Live Writer introduces a set of APIs which can be used by weblog providers to customize both the capabilities of Writer as well as add new capabilities to the Writer user-interface. Available customizations include:</p>
<ul>
<li>Defining the subset of weblog features supported by the weblog. This allows providers to implement any subset of the core XML-RPC based weblog APIs (Metaweblog, Movable Type, or Wordpress) and have Writer&#8217;s UI correctly respect this subset. </li>
<li>Provide the correct URL entry points for viewing and managing the weblog as well as editing posts online. </li>
<li>Define a custom icon and watermark image that appears in the Writer Sidebar </li>
<li>Define custom buttons that can link to web-pages, display content in a drop-down, and notify the users of new content and other online activity. </li>
<li>Define WYSIWYG editing templates for the active weblog theme. </li>
</ul>
</blockquote>
<p><a rel="lightbox" href="http://blog.sharplab.net/wp-content/uploads/2008/05/image4.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="213" alt="image" src="http://blog.sharplab.net/wp-content/uploads/2008/05/image-thumb1.png" width="244" align="right" border="0" /></a>んー、Provider Customization APIは、Blogサービス提供者が自分の提供するサービスと適合するようにWLWをカスタマイズするためのAPIということなのかな？このAPIをうまく使ってやれば、アカウントセットアップ時に右図のように表示されるサービスの一覧に自分のサービスを追加できるのだろう。多分。</p>
<p>ということで、Content Source Plugin APIとApplication APIは大分使えそうな印象。あー、Sleipnirがプラグイン作成用SDKを公開してくれていれば、すぐにでもApplication APIを使用して引用記事を書くプラグインを作るのに。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sharplab.net/computer/cprograming/windowslivewriter/167/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
