プログラマ ずんべ の日記

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」と入力してください。


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