スクリプト8 (*Wait コマンド)


*Waitコマンドについてです。*Waitコマンドは指定した秒待つという機能ですが実は他にも様々な「待ち方」があります。 これらを使うと意外に便利な使い方が見つかるかもしれません。

◆ 指定した秒数待つ

これは*Waitコマンドの基本の使い方です。単に指定した秒数だけ待つだけです。構文は次のようになります。

*Wait n

n には待たせたい時間を秒単位で指定します。例えば間を3秒間置きたいと思ったら次のようにします。

*Wait 3

秒単位ではなくミリ秒単位で指定することもできます。それには「sleep」というキーワードを使います。 構文は

*Wait sleep m

となり、m には待たせたい時間をミリ秒単位で指定します。例えば200ミリ秒待たせたいと思ったら

*Wait sleep 200

とします。


◆ ready

キーワード「ready」はウィンドウが入力を受け付ける状態になるまで待つキーワードです。 これを使うのは何かのプログラムを起動させた直後になることが多いと思います。 プログラムの中には重くて立ち上がるのに時間のかかるものがあります。そのプログラムを起動した後に 何かしたいと思ったときにこれを入れます。「ready」を使わなかった場合は意図した通りにスクリプトが動かない可能性が あるので特にプログラムを起動させたあとそのプログラムに対して何かしたいと思ったときは「ready」を使うことをお勧めします。

構文は次のようになります。

*wait ready captionlist

captionlistにはキャプションリストを指定します。 しかしこのcaptionlistはオプションで指定しなくてもいいです。 指定しなかった場合はPowerProが直前に起動させたプログラムがターゲットとなります。例えば次のスクリプトのようにメモ帳を起動させたあと *Wait readyを入れると

notepad
*Wait ready

自動的にメモ帳が入力を受け付ける状態になるまで待つ、ということになります。もちろん明確に待つアプリケーションを指定してもかまいません。 例えば先の例なら

notepad
*wait ready =notepad

としても同じです。しかし普通は直前に起動させたプログラムを待つことが多いのでターゲットを省略することの方が多いでしょう。


◆ done

キーワード「done」はプログラムが終了するのを待つキーワードです。しかし私のところでは使い方が悪いのか 動作を確認することができませんでした。なのでここで書くことは推測です。各自試してみてください。

構文は次のようになります。

*Wait done captionlist

ほぼ「ready」と同じような使い方をします。「ready」同様captionlistはオプションで、 指定しなくてもかまいません。その場合は直前にPowerProが起動させたプログラムがターゲットとなります。 captionlistを指定する場合はそのキャプションリストに合うウィンドウが表示されてなければ ならないそうです。


◆ active、noactive

「active」は特定のウィンドウがアクティブになるまで、そして「noactive」は特定のウィンドウが非アクティブになるまで 待つキーワードです。この2つは互いに反対の関係です。構文は

*Wait active captionlist

*Wait noactive captionlist

となります。このcaptionlistはreadyやdoneのように省略できません。

例えばメモ帳が非アクティブな状態でそれがアクティブになったら何かしたいと思ったら次のようにします。

*wait active =notepad

メモ帳がアクティブになるまで待ちます。この「active」を「noactive」にすると逆にメモ帳が非アクティブになるまで待つことになります。

また待つ秒数を制限することもできます。つまり〜秒までにアクティブ(または非アクティブ)にならなかったら待つのをやめて次のコマンドを実行する、ということです。 それをするにはキャプションリストの前に数字を書きます。もちろん数字は制限する秒数です。例えばメモ帳がアクティブになるのを待つけど 10秒以上経ってもアクティブにならなかったら次のコマンドを実行してしまうよ、というときは次のようにします。

*wait active 10 =notepad

こうすると10秒経ってもアクティブにならなかったら次のコマンドを実行するようになります。

◆ window、nowindow

「window」は特定のウィンドウが起動されるまで、「nowindow」は特定のウィンドウがなくなるまで待つキーワードです。 つまりこれらを使うと特定のプログラムが起動するまで、または終了するまで待つことができるということです。構文は

*Wait window captionlist

*Wait nowindow captionlist

となります。captionlistは省略できません。

例えばメモ帳が起動したら何かしたい、と思ったら次のようにします。

*wait window =notepad

もちろんメモ帳を起動させる前にこのコマンドを実行しておかなければなりません。この「window」を「nowindow」に 変えれば逆にメモ帳が終了するまで待つということになります。また「active」などと同様に待つのを秒数で制限することができます。 キャプションリストの前に制限する秒数を書いてください。


◆ path、nopath

「path」は特定のパスのプログラムが実行されるまで、「nopath」は特定のパスのプログラムが終了するまで待つキーワードです。 これらはターゲットの指定方法が違うだけで「window」や「nowindow」とほぼ同じ機能です。構文は

*Wait path "c:\path\prog.exe"

*Wait nopath "c:\path\prog.exe"

となります。"c:\path\prog.exe"のところにはターゲットとなる実行ファイルへのフルパスを 指定します。キャプションリストは使えないようです。パスに空白を含む場合は必ずダブルクォーテーションで囲ってください。

例えばメモ帳が既に起動していて終了するまで待ちたいというときは次のようにします。

*wait nopath "c:\windows\notepad.exe"

メモ帳が終了するまで待ちます。メモ帳のプログラムへのパスは人によって違うかもしれません。


◆ message

指定した秒数カウントダウンするキーワードです。実行すると次のようなダイアログが表示されカウントダウンされます。



この秒数が0になると次のコマンドが実行されます。 「Start Now」のボタンを押すとカウントダウンをやめ直ちに次のコマンドを実行します。 「Cancel」のボタンを押すとカウントダウンを中止しさらに次のコマンドも実行しません。構文は

*Wait message n text

となります。n にはカウントダウンさせたい秒数を指定します。 textにはカウントダウンダイアログに表示させたい文字列を指定します。 例えば先の図のようにダイアログに「*wait messageのテスト」と表示させたい場合は次のようにします。

*wait message 10 *wait messageのテスト

この場合10秒カウントダウンするように指定しています。


◆ activity

マウスやキーボードを操作するまで待つキーワードです。キーボードのキーを押したりマウスを動かしたりすると待つのをやめます。 構文は

*Wait activity

でパラメータなどありません。これを実行したあと3秒間だけは準備期間としてマウスなどを動かしてもいいようになっています。 3秒経つと有効になってマウスなどを操作すると待つのをやめて次のコマンドを実行します。


◆ ctrl、alt、shift、noctrl、noalt、noshift

「ctrl」、「alt」、「shift」はそれぞれctrl、alt、shiftキーが押されるまで待つ、「noctrl」、「noalt」、「noshift」はそれぞれctrl、alt、shiftキーが 離されるまで待つキーワードです。構文は

*Wait ctrl

だけです。上の例では「ctrl」の場合ですが他のキーワードも全て同じ書き方です。パラメータなどありません。 例えばshiftキーが押されるまで待ちたいと思ったら

*wait shift

とします。これでshiftキーが押されるまで待つことになります。shiftキーが押されると次のコマンドを実行します。 ただ少し反応が悪い感じがするので少し長めにキーを押すといいです。


◆ 待っている*Waitコマンドの停止

ここでは条件を満たしてなくてまだ待っている状態の*Waitコマンドの停止方法について書きます。 ときにはまだ待っている*Waitコマンドを停止させたいときがあるかもしれません。 そのようなときは次のコマンドを実行します。

*Wait quit

これを実行すると全ての待機中の*Waitコマンドが停止します。


◆ nowindow、nopathの応用

ここはウィンドウをモニターする その2の別の方法についてです。 ウィンドウをモニターする その2では「Internet Explorerが起動したらProxomitronを起動させ、 Internet Explorerが終了したらProxomitronも終了させる」ということをやりました。 しかしモニタリング機能を使って毎秒スクリプトを実行するのは負荷がかかります。 そこでここではOpenスペシャルリストと*Wait nowindowまたはnopathを使って同じことをもっと負荷をかけずに 行う方法を書きます。

動作原理は簡単です。まずOpenスペシャルリストにInternet Explorerを登録しておきInternet Explorerが起動したときに スクリプトを実行させるようにします(OpenスペシャルリストについてはSpecial Listsについてを 見てください)。そのスクリプトの中でProxomitronを起動させ*Wait nowindow "=iexplore"(またはnopath)を実行しInternet Explorerが 終了するまで待ちます。Internet Explorerが終了したらProxomitronを終了させます。以上でほぼ同じ動作が可能です。簡単ですね。

早速スクリプトを作りましょう。作るスクリプトはInternet Explorerが起動していることを前提として作ります(Openスペシャルリストで実行するので)。 スクリプトは次のようになります。

;Proxomitronが起動していなければProxomitronを起動
if(anywindow "=Proxomitron" == 0)
    "C:\(Proxomitronへのパス)\Proxomitron.exe"
endif
;Internet Explorerが終了するまで待つ
*wait nowindow "=iexplore"
if(anywindow "=Proxomitron")
    *window close2 "=Proxomitron"
endif

そんなに難しい事をしていないので大体わかると思います。最初にProxomitronの二重起動を防ぐためにProxomitronが起動していないかを 調べてからProxomitronを起動しています。次に*window nowindow "=iexplore"でInternet Explorerが終了するまで待っています(nopathでも同じことができます)。 Internet Explorerが終了したら、Proxomitronが起動していることを調べてからProxomitronを終了させます。ここで*window closeではなく *window close2(Ver3.8以降の機能)を使っているのはcloseコマンドではうまくProxomitronが終了できなかったためです。close2だとうまく 行きました。

あとはOpenスペシャルリストにアイテム名「=explore」のアイテムをつくりこのスクリプトを実行するようにすれば 「Internet Explorerが起動したらProxomitronを起動させ、Internet Explorerが終了したらProxomitronも終了させる」 という動作が実現できます。

しかしこの方法だと一つ問題があります。それはInternet Explorerが複数起動させられた場合です。 Internet ExplorerのようなSDIブラウザではウィンドウが複数起動されるということが多いです。 Openスペシャルリストでは実行ファイルが実行されるたびに反応してしまいます。Internet Explorerが 一度起動させられていようがいまいが関係なく実行されてしまうのです。つまりウィンドウが複数起動させられると その分だけスクリプトが走ることになるのです。動作自体には特に問題ないのですがやはり気持ちが悪いですね。また*window nowindowが複数 実行されてしまうのも問題です(あまり多いとメッセージが出ます)。 Donutのようなタブブラウザなら問題にならないと思います。

この問題を解決する方法として変数を使ってスクリプトが走っているかをチェックする方法があります(他にもいろいろやり方はあると思います)。 変数を使って先の*Waitコマンドが実行されているかを調べ既に実行されていれば*waitコマンドを実行しないようにすればいいのです。 スクリプトを書くと次のようになります。

global g_flag
;*Waitコマンドが既に実行されていれば終了
if(g_flag == 1)
    quit
endif
;Proxomitronが起動していなければProxomitronを起動
if(anywindow "=Proxomitron" == 0)
    "C:\(Proxomitronへのパス)\Proxomitron.exe"
endif
g_flag = 1
;Internet Explorerが終了するまで待つ
*wait nowindow "=iexplore"
if(anywindow "=Proxomitron")
    *window close2 "=Proxomitron"
endif
g_flag = 0

先のスクリプトに少し変数を加えただけです。最初にグローバル変数としてg_flagを作っています。 g_flagをフラグとして*waitコマンドが走っているかどうかを調べるのです。このスクリプトではg_flagが1のときは *waitコマンドが走っている、0のときは走っていない、と判断します。

一番最初にこのスクリプトを実行したときは変数g_flagが作成され、このときg_flagは0で初期化されます。 なので一番最初は2行目のIf文でquitは実行されません。その後*waitコマンドを実行する直前でg_flagを1に設定し *waitコマンドが走っている、という目印を立てます。

この*waitコマンドが走っているときに、もう一度このスクリプトを実行するとg_flagは1の状態なので2行目のif文で真となりquitが実行され そこでスクリプトが終了します。つまりすでに*waitコマンドが走っているときはその後にある*wait文は実行されないという仕組みです。 こうすることで*waitコマンドが多重に実行されることを防ぐのです。

Internet Explorerが終了すると*waitも終了しあとは先と同じ動作です。ただし最後で*waitコマンドが走っていないことを 示すためにg_flagを0にしておく必要があります。ちなみにグローバル変数はPowerProが終了するまで保持されます。


スクリプト7へ  トップへ  スクリプト9へ