プログラマ ずんべ の日記

zunbe

プログラマ ずんべ の日記
プログラマ ずんべ の日記

探し物は見つかりましたか? サイト内検索を試してください。

不思議に思うこと - 自転車のカギ 不思議に思うこと - 自転車のカギ 愛知県知事選挙 愛知県知事選挙

2007/02/02

【技術開発】IIS で KAKASI.EXE を実行する

久しぶりのプログラミングねた。

IIS上でわかち書きをするプログラムを作成した。
使用したわかち書きモジュールは KAKASI Win32
WEB のフォームから入力された文章を、KAKASI を使用してわかち書きしようとトライした。

まっとうな方法としては…

 (1).KAKASI Win32 に含まれているライブラリを呼び出す ActiveX を作成し、
 (2).それを Windows にインストールし、
 (3).IIS上から Server.CreateObject() でオブジェクトを作成して利用する。

であろうが、サーバ機は手元にあるわけではないし、Administrator 権限をもっているわけでもないので、ActiveX から呼び出す方法は選択したくない。
そこで、実行プログラムである KAKASI.EXE をIIS上から起動して実装する事にした。

実行プログラムをIIS上から起動する方法はいろいろあるのだが、どうも、うまくいかない。
まず、前提として、以下の問題がある。

 KAKASI.EXE は、標準入力から文章を読み込んで、標準出力に吐き出すフィルタである。

KAKASI.EXE のオプションに、入力ファイル、出力ファイルを指定するオプションは無い。
つまり、KAKASI.EXE を使用するためには、パイプライン/リダイレクトを使用した形で実装する必要がある。

■方法1…BASP21の Execute() を使用する

とりあえず、もっとも簡単そうなので、試してみた。

が、BASP21 の Execute() は、標準入力からデータを流し込む事ができない。
仕方がないので、ソースの文章を一旦ファイルに書き出しておいて、TYPEコマンドでファイルを読み出し、パイプで KAKASI.EXE に流し込むようにしてみる。

 Set objBASP = Server.CreateObject("basp21")
 rc = objBASP.Execute("CMD.EXE /c TYPE 入力.txt | KAKASI.EXE -w", 1, o)

このコードを実行すると、見事にフリーズした。
IISは生きているようだが、ブラウザは返ってこない。
KAKASI.EXE が、標準入力のクローズを待っているようだ。
これはきっと、UNIX で言うと、こんなコマンドを打ったような状態だろうか。

 cat

延々と標準入力がクローズされるのを待ちつづけている感じ。

もしかして、標準出力へ吐き出せないのかと疑って、以下のコードも試してみた。

 Set objBASP = Server.CreateObject("basp21")
 rc = objBASP.Execute("CMD.EXE /c TYPE 入力.txt | KAKASI.EXE -w > 出力.txt", 1, o)

「出力.txt」は作成されるが、サイズは0バイト。
テキストエディタで開いても、ロックがかかっていて書き込めないというエラーが表示される。
つまり、IISが出力ファイルとして、このファイルを捕まえているという事であろう。
これはきっと、UNIX で言うと、こんなコマンドを打ったような状態だろうか。

 cat > 出力.txt

出力ファイルを作成して、延々と標準入力がクローズされるのを待ちつづけている状態か。

ちなみに、以下のコードは、きちんと「入力.txt」の内容を出力できる。

 Set objBASP = Server.CreateObject("basp21")
 rc = objBASP.Execute("CMD.EXE /c TYPE 入力.txt", 1, o)

つまり、「入力.txt」が読めていないわけではない。
と、いう事は、BASP21 の Execute() 内では、パイプが使えないという事なのだろうか。

■方法2…WshShell の Exec() を使用する。

Exec() は、標準入力からデータを流し込んで、標準出力から取り出す流れになるので、もっとも望んでいる形なのだが、やはりうまく動かない。

 Set objShell = Server.CreateObject("WScript.Shell")
 Set objExec = objShell.Exec("KAKASI.EXE -w")
 Call objExec.stdin.Write("入力")
 Call objExec.stdin.Close()
 o = objExec.stdout.ReadAll()

フリーズはしないが、出力は常に空。
試しに、同じコードを WSH にして実行してみると、きちんと動作する。
プログラムがおかしいわけではない。
どうも、IIS上ではパイプラインをうまく通せないようだ。

困ったゾ。

■方法3…WshShell の Run() を使用する。

Run() は、標準入出力を扱えないので、入力、出力とも、テンポラリ・ファイルを介するようにするしかない。

 Set objShell = Server.CreateObject("WScript.Shell")
 Call objShell.Run("CMD.EXE /c TYPE 入力.txt | KAKASI.EXE -w > 出力.txt", 0, True)

おっ!
うまくいった。(^^)
わかち書きされたテキストが、「出力.txt」に吐き出された。
どうやら、Run() は、姑息な事はせずに、渡されたコマンドラインをそのまま実行する単純な動作の様だ。
おそらく、完全に分離されたシェル起動して、IISとは干渉しない世界で動作するのだろうな。
いちいちテンポラリファイルを介する必要があって、いちいちシェルが起動されるようなので、処理速度的には難があるように思うが、とりあえず、これでOK。
近いうちに、ActiveX からの呼び出しをトライしてみよう。

しかし、IIS上でパイプラインがどうにもうまく働かないのは、少し解せない。
パイプラインくらい、Windows というシステム全体の中で、一貫して動作して欲しいのだが、様々な場面で、いろいろ挙動が変化するのは、きっと、海よりも深いわけがあるんだろうな。




このエピソードはいかがでしたか?

投稿者 zunbe : 2007/02/02 09:50:16


トラックバック 〔http://blog.zunbe.com/mt/mt-tb.cgi/569〕

【プログラマ ずんべ の日記】 IIS で KAKASI.EXE を実行する(2)
このエピソードの続き。  2007/02/02 IIS で KAKASI.EXE... IIS で KAKASI.EXE を実行する(2)

トラックバック時刻: 2007/04/14 11:06:52


コメント

このKAKASI Win32って、Apacheが前提になってたりして。
後は、Perlから呼び出すとかしかないのかな・・。

やはり、ASP.NETで記述してもらわないと・・。

パイプの機能は、無理矢理くっつけた感じがあるから、謎になるのは当たり前だと思う。

投稿者 チャーリー栗原 : 2007/02/03 03:38:46

●チャーリー栗原さん

> このKAKASI Win32って、Apacheが前提になってたりして。

なはは。
まぁ、でも、そんな事はないと思いますよ。
KAKASI.EXE 自体は、単なるアプリケーション・プログラムですから、プログラムの動作自体とプラットフォームは関係が無いと思います。
ちなみに、Windows標準の SORT.EXE でも同様に動きませんので、KAKASI の問題ではないと思います。

> やはり、ASP.NETで記述してもらわないと・・。

現在稼動しているお客様のマシンの環境に依存なので、ASP.NET 化はちょっと無理だす。

> パイプの機能は、無理矢理くっつけた感じがあるから、謎になるのは当たり前だと思う。

それは確かにそうだと思いますが、システムとして片手落ちな感はちょっとしますです。

投稿者 ずんべ : 2007/02/03 14:04:33


コメントしてください






保存しますか?


スパム対策:
この入力フィールドに「667」と入力してください。


プログラマ ずんべ の日記:ずばヒット アマゾン