miau's blog?

サクラエディタ WSH マクロの Ruby、PHP、Phython 対応

[412] マクロをRubyで書きたい - サクラエディタ マクロBBS

ここで「Ruby でマクロ書けないの?」という話が出てたので対応パッチ作ってみた。

SourceForge.net: Modify: 1929358 - WSH マクロの Ruby、PHP、Phython 対応

Ruby だけじゃなくて PHP や Python にも対応してます。バイナリへのパッチじゃなくてソースへのパッチなので、ひとまずコンパイル環境持ってる人向け。マクロBBS にも書いたけど、本家に取り込まれるかどうかは

[5281] WSH マクロの Ruby、PHP、Phython 対応 - SAKURA Development BBS (ANSI)

ここの反応次第だと思う。

以下今回の対応詳細です。長いので注意。




■WSH の開発者向け情報

WSH のクラスその他については、以下のページに説明がある。

Windows Script Interfaces

でもこれだけだとわかりにくいので、旧バージョンのシーケンス図っぽいのを見ておいたほうが理解が深まるかも。

Microsoft Windows Script Interfaces-Introduction

今回のケースだとサクラエディタが scripting host で、PHP やら Ruby やらのエンジンが scripting engine に当たるってことで。

■実装サンプル

はじめは PHP や Ruby の呼び出しをデバッグモードで追ってたんだけど、Scripting host の実装サンプルを見つけた。

Axsh.exe demonstrates how to implement an active scripting host

これの挙動と比べたほうが手っ取り早そうなので、その方法で調査を進めた。PHP や Ruby のデバッグやコンパイルについては、またの機会にネタにしようかと。

■各エンジンのインストールについて

こちらによくまとまっています。

EmEditorのマクロを様々なActiveScriptで書いてみる - テキストエディタ

PHPScript については、.msi のインストーラで PHP→Extensions→Activescript にチェックを入れておけば PHP/ext/php5activescript.dll が勝手にできるはずなので、そのほうが楽かもしれません。もし後述 .reg を使う場合は、念のため PHP→Program→Script Executable→Register *.php も選んでおいたほうがいいと思います。

■調査結果と対応内容について

各言語のインストールについては末尾の参考 URL を見てください。

○Ruby(ActiveScriptRuby)

Ruby マクロを動かすとサクラエディタが落ちてたんだけど、これは AddNamedItem で SCRIPTITEM_GLOBALMEMBERS を指定しなければ解決するみたい。

IActiveScript::AddNamedItem

によると、SCRIPTITEM_GLOBALMEMBERS ってのは追加したオブジェクト(今回でいう Editor)の各要素をグローバルで見れるようにするものらしい。なるほど。それで今まで Editor.InsText("hoge"); と書かずに InsText("hoge"); と書けてたのか。

このフラグを削ると下位互換がなくなる(古いマクロで動かなくなるものもあるかもしれない)わけで、どうするか悩むところ。個人的には Ruby は結構重要ありそうだし対応入れちゃってもいいんじゃないかなと思う。グローバルにメンバがあると、オブジェクトをうまく扱えない言語で便利そうではあるんだけど・・・そもそもオブジェクトを使わずに WSH を使うのが大変そうなので。(後述。Haskell の辺り。)

なお Ruby のマクロは拡張子を .rb で書きます。.rbs ではないので注意。

○PHP(PECL::PHPScript)

まず前提となる動作説明。ブラウザなんかで WSH を使う場合は <script language="PerlScript"> みたいな感じで ScriptEngine を指定するんだけど、サクラエディタや cscript、wscript は拡張子を元にレジストリを調べて ScriptEngine を取得してる。

(例) PerlScript(拡張子 .pls)の場合

HKEY_CLASSES_ROOT\.pls\ →PerlScriptFile
HKEY_CLASSES_ROOT\PerlScriptFile\ScriptEngine\ → PerlScript

と辿ることで ScriptEngine の名前が「PerlScript」であることを知ることができるというわけ。

ところが PHP はレジストリに ScriptEngine を登録してくれないので、自分で登録する必要がある。その拡張子を .php にするか .phps にするか悩んだけど、本家で決めることだと思うので要望を出しておいた。

PECL :: Request #13538 :: .php file can't be executed by cscript.exe

今回はより設定項目が少ない .php でやってみた。その場合のレジストリ追記用 .reg ファイルについては、Patch と一緒にアップロードしてるのでそちらを使ってください。(よく考えたら PHP インストール時に .php の関連付けをやってないと HKEY_CLASSES_ROOT\.php\ → PHPFile の設定が無いかも・・・。)

で、ここからが本題。挙動を調査したところ、CWSHSite::CWShQueryInterface で IID_IActiveScriptSite や IID_IUnknown にも S_OK 返さないと動かないみたい。この変更は下位互換あるから問題なし。

○Python

CInterfaceObject::Invoke で wFlags == DISPATCH_PROPERTYGET にも反応してたのがまずいっぽい。この部分を修正すれば一応動いた。マクロの拡張子は .pys で。

でもなぜだか VC++ 経由で起動したプロセスではうまく呼び出せない(サクラが落ちる)。詳細不明だけど、別プロセスにアタッチした場合はちゃんと動作してるので VC++ 2005 EE の問題か何かかなと思ってる。

■挫折したもの

○Tcl

TclScript: Tcl Active Script Engine

という scripting engine がある。最終更新が 2001-07-23 なので少々不安。
(scripting engine として ActiveTcl を紹介してる人もいるけど・・・これって scripting engine 含まれてないよね?)

で、TclScript をインストールしようとしたけど、regsvr32 でエラーになってしまう。ドキュメントに「The dll is a debug build linked with Tcl and Tk 8.3.」なんてことが書いてあったから、古い Tcl を探さないといけないのかな?

サンプルとか見てみたけど、もし動かせたとしてもオブジェクト扱うのが難しい気がする。あまり便利じゃなさそうなので深みにはまる前にやめておいた。

○Haskell

HaskellScript: About

こちらも最終更新が 1999 年の 5 月ということで不安だったけど、Haskell98 って現時点でも最新の仕様って聞いてるし、インストール自体はうまくいったので試してみた。
「The HaskellScript libraries are written in Haskell98 and compatible with both Hugs98 and GHC 4.0+.」って書いてるけど、GHC じゃ動かないので Hugs98 も入れる必要あり。オートメーション周りのライブラリは GHC でも動作するって意味かな。

で、HTML やら WSH やらのサンプルはちゃんと動作したんだけど、active scripting host の実装サンプルから呼びだすとなんか変なエラー。構文エラーとかじゃないので、スクリプトは間違ってないと思うんだけどなぁ。

import qualified HScript
import qualified Automation

main :: IO ()
main = do object <- HScript.getHostItem "MyObject"
Automation.method_0_0 "SayHi" $ object

実装サンプルからも動作しないので半ばあきらめつつ、サクラエディタでも動かしてみた。たぶんこんな感じで拡張子 .hash のファイルを作ればいいはず。

import qualified HScript
import qualified Automation

main :: IO ()
main = do editor <- HScript.getHostItem "Editor"
Automation.method_1_0 "InsText" "test" $ editor

エラーにはならなかったけど、ちゃんと動作してくれないみたい。
まぁ使えるようになったとしても、上記のように結構記述が冗長になってしまう。OOP がベースとしてある WSH の世界には、関数型言語は向かないのかも。

サンプルでは

import HtmlScript

main :: IO ()
main = do window <- theWindow
window # alert "Haskell Script Running !"

これくらいまでシンプルに書けるようにしてあったけど、これはモジュール側で window.alert を宣言してるからだったり。利用側でも各メソッドを宣言しないといけないって、それだと WSH の恩恵があまり受けられないような。そんなわけであまり意味ないようなので調査打ち切り。

■その他情報源

○実装サンプル

How to add support for hosing VBScript to your MFC application

CodeGuru: Implementing Active Script Site with ATL

上のほうで挙げた scripting host サンプルはベタな VC++ での実装だったけど、こっちは MFC や ATL でのサンプル。この辺とちゃんと見比べたら Haskell 動作できるようになるかも。(やる気ないけど。)

SamScrpt.exe sample demonstrates implement Active Debugging in an ActiveX Script Engine built in straight C++

scripting engine のほうを実装する場合のサンプル。いずれこっち方向にも手を出すかもしれないのでメモ。

■その他個人的なメモとか

Windows Script Wiki - リンク

なんだか色々便利そうな情報あるのでメモ。

BSTR 覚え書き

デバッグ中に LPOLESTR の出力方法わからなくて調べたら見かけた。メモメモ。

PerlScript - miau's blog?

ここで紹介した ComTrace も調査に使えるかなと思いつつ忘れてた。次回用メモ。

Active Scripting - Wikipedia, the free encyclopedia

Active Script の説明ページ。ここに Haskell って書いてなければこんなに調査時間食わなかったのになぁ。

それにしても、「ActiveScript」でググると「もしかして:ActionScript」とか言われるのはなんとかならないのかな。もしかしないよ。
posted at 02:19:19 on 2008-03-31 by miau - Category: TextEditor No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

FILE wrote:

 お世話になっております。

 非常に興味深いパッチですが、開発掲示板(ANSI)では反応がいまいちですね。

 ・1.ActiveScriptRubyで「SCRIPTITEM_GLOBALMEMBERSフラグ」に関する記述を見つけました。
   参考になりますでしょうか。

   メモ:ASRにデフォルトオブジェクトを組み込む
   arton.no-ip.info/diary/20061104.html

 ・2.(未確認で申し訳ないのですが、)JScript/VBScriptから、他スクリプト言語で記述した
   .wscファイルを呼び出した場合の動作が気になりました。
   #現時点でも動作するのか とか、ホストするのは誰なのか とか。

   Windows Script Componentの使用
   http://www.geocities.jp/mar...

 ・3.以前、当方もAxsh.exeを参照しましたが、当時のサクラエディタの実装と少し
   異なっていたような記憶があります。#詳細は忘れました。

 ・4.上記記事の「対応詳細」は、サクラエディタの「アウトライン解析」対応なんですね。
   きれいにまとまっていて、読みやすかったです。

 ・5.こちらの環境(IE)では、「Add Comments」の部分のレイアウトが少し崩れています。
   各入力要素間に改行<br />を入れていただけますと、分かりやすくなると思いますが
   いかがでしょうか。#現状でも、特に問題はありませんけど一応。

 コメントが長くなってしまいました。申し訳ありませんm(_ _)m。
 今後もよろしくお願いいたします。
2008-04-05 01:25:54

miau wrote:

コメントありがとうございます。
現時点でわかるところから回答させていただきます。

>・1.ActiveScriptRubyで「SCRIPTITEM_GLOBALMEMBERSフラグ」に関する記述を見つけました。

てっきり ASR が SCRIPTITEM_GLOBALMEMBERS に対応していないのかと思ったんですが、ちゃんと対応しているようですね。
Axsh.exe でこのフラグを指定して試してみたんですが、MyObject.SayHi の代わりに sayHi としても呼び出し可能でした。(定数とみなされないよう先頭を小文字にする必要があるようです。)
がんばれば SCRIPTITEM_GLOBALMEMBERS にも対応可能ということなので、もう少し調べてみようと思います。

>・3.以前、当方もAxsh.exeを参照しましたが、当時のサクラエディタの実装と少し
>   異なっていたような記憶があります。#詳細は忘れました。

Axsh.exe とサクラエディタの実装で大きく異なるのは TypeInfo の作成方法かなと思います。Axsh.exe では .tlb ファイルから読み込んでいるだけですが、サクラエディタでは自前でクラスを実装しています。後者の実装サンプルがないので、どうするのが正しいか判断できなくて困ってます。

----

blog 記事のアウトライン解析対応は指摘されるまで気づかなかったんですが、サクラエディタのアウトラインに慣れてるせいでこの書き方が自分の中に定着してしまっているようです。(メールなんかでもこの書き方をしています。そういえば。)本当はちゃんと HTML タグ使ったほうがいいんでしょうね・・・。

コメント欄についても、私はログインした状態で使用しているので気づきませんでした。(こういうご指摘は本当に助かります。)折を見て直そうと思います。
2008-04-07 16:55:07

FILE wrote:

 ご回答ありがとうございます。

 ・6.Rubyの「SCRIPTITEM_GLOBALMEMBERS」について
   環境が無いので試す事が出来ませんが、以下によると頭に「$」を付けるだけかもしれません。
   #例えうまく動作したとしても、「$」が無くて落ちてしまうのはどうかと思いますけれど。

   arton.hp.infoseek.co.jp/
   > ASR's new features since 1.1.0
   > 2. support global member's attributes as global variable. ($ + CaseSensitive name)

   掲示板のチェックボックス案以外にも、Rubyの場合だけ無指定にしてしまうのも手(抜き?)だと思います。
   ScriptEngineの数はあまり多くないでしょうし、個別に対応という事で。

 ・7.Axsh.exe とサクラエディタの実装の相違
   TypeInfoの自前実装は、当時、検索しても見つけることが出来ませんでした。
   当方の感じた相違点は、SetScriptSite()等の呼び出し順だった様な気がします。(うろ覚え)

 ・8.コメント欄の折り返し
   現在、きちんと折り返されて表示されています。

   display: block; で修正していただけたのでしょうか。
   素早いご対応、ありがとうございました。

 ・9.他スクリプト言語の使用手段
   Windows Script Component(.wsc)以外にも、「ScriptControl」等の手段がありますね。
   現状でも、他のスクリプト言語を使用している方がいるかもしれません。

   Re: 呼び出し元アプリの情報取得方法
   http://www.vbstation.net/qa...

 ・10.ScriptEngineの取得に関する情報がありました。

   ActiveScript探索メカニズム
   arton.no-ip.info/diary/20051218.html

 またまた、コメントが長くなってしまいました。
 ご参考になれば、幸いです。
2008-04-18 20:38:16

miau wrote:

毎度丁寧なコメントありがとうございます。

とりあえず私の方針ですが、ASR が SCRIPTITEM_GLOBALMEMBERS に対応しているとわかった以上は、なるべくちゃんと実装したいと思ってます。

ただ、FILE さんもおっしゃているように ITypeInfo を使う方法は Web に情報が少なく、参考になりそうな書籍も絶版になっています。
(中古で探しても、http://www.amazon.co.jp/gp/... のようにすごい値段が設定されていて手が出せません・・・。)

ただいま原著を取り寄せ中ですので、それ読んで対応できそうならするし、対応できないようならチェックボックスを設けるなり Ruby だけ無指定にするなりの対応を検討しようと思います。
書籍が届くのは来月中旬以降の予定ですので、無責任ですみませんがそれまでは調査保留しちゃおうかなと。。(この本に全部書いてたりしたらもったいないので。)

----

>頭に「$」を付けるだけかも

ParseScriptText() よりも前に落ちているので、スクリプトの書き方が問題なわけではなさそうです・・・。

>コメント欄の折り返し

Nucleus の掲示板を参考に CSS 変更させていただきました。
http://japan.nucleuscms.org...
2008-04-21 02:12:56

miau wrote:

Amazon から配送遅延の連絡があり、書籍が届くのは 6 月中旬以降とのことです・・・。調査もそれ以降ということで・・・。
2008-05-23 03:04:08

miau_ wrote:

Amazon から再度連絡があり、実は在庫がなかったとのことです。別のところで再注文したので、さらに 2〜3 週間かかります・・・。
2008-06-12 00:17:33

miau wrote:

状況報告。一週間くらい前に Automation Programmer's Reference( http://www.amazon.co.jp/gp/... )は手元に届いてるんですけど、本業が忙しくて読む暇がない、というところです。。
2008-07-13 09:25:21

FILE wrote:

 似た名前のページを発見。
 msdn.microsoft.com/en-us/library/ms221375(VS.85).aspx
2008-07-17 00:38:32

miau wrote:

反応遅くてすみません。一ヶ月ほど時間が止まっていたかのような忙しさでした。

>似た名前のページを発見。

見比べてみたんですけど、書籍の 7 割くらいを占めるリファレンス部分の内容がこのページで網羅されている気がします・・・orz

でも Web ページだと分散していて見落としそうな情報がきっちりまとまっているので、購入したのは無駄ではない・・・と前向きに考えることにします。
2008-08-15 07:14:25

miau wrote:

Referer 経由で参考になりそうなページを見つけたので、とりあえずメモ。

anon_193の日記
http://d.hatena.ne.jp/anon_...

2009-02-24 あたりから WSH の話題があり、個別の scripting engine について色々対応されているようです。
2009-03-24 06:41:09

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。