• ベストアンサー

VBScriptの無限ループ動作で簡単終了方法

お世話になります。 私のPCでは、監視のために無限ループ動作のVBScriptが三つほど動いています。それでメンテナンスでどれかの一つを停止(強制終了)しようと、タスクマネージャーにアクセスしてもイメージ名が皆同じで、区別がつかず困るときがあります。 そこで、最初からこの無限ループ動作のスクリプトに仕込みをしておいて、いつでも簡単に終了させる方法などありますか。検索してもまったく見つかりませんでしたので、相談させて頂きました。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4903/10364)
回答No.3

わたしが常駐型を作るときは、 cnt = 0 for each p in GetObject("winmgmts:{impersonationLevel=impersonate}"). _ ExecQuery("select * from Win32_Process where Name='wscript.exe'") if instr(p.CommandLine,""""&WScript.ScriptFullName&"""")>0 then cnt = cnt+1 end if next で、そのスクリプトの起動数を調べ、 if 起動数が2以上 then  すでに常駐しているものを止めるかどうかをダイアログで聞いて、OKなら、自分以外のそれをQuitさせる  自分自身はそのまま終了 else  常駐して本来の処理 endif つまり、 ・スクリプトを起動する⇒常駐する ・もう一度スクリプトを起動する⇒常駐しているさっきのプロセスを止めるかどうか聞いてくる という使い方をしています。 もっと簡単には、Microsoft Sysinternalsのサイトから、ProcessExplorerをダウンロードして、それをタスクマネージャの代わりに使うと、プロセスのコマンドラインが見えるので、それを見てどのスクリプトか判断して止めれば、プログラムを修正せずにすみます。

okwavewan
質問者

補足

ご返事ありがとうございます。 LOCKの部分をこれに置換えるのですね。このカウンタのアイデアはいいですね。使わせて頂きます。 ProcessExplorerは、話に聞いていましたが、今回ダウンロードしてみました。なかなかの高性能ですね。 今回は色々のアドバイスありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • Reginleif
  • ベストアンサー率37% (9/24)
回答No.2

なるほど。。 スリープ処理はあるけれどBreakするまでのインターバルの問題がある、ということですね。 となればプロセスIDを元にKILLが一般的になりますね。 対応例としては別途起動用プログラムを作成 FormLoad等で監視スクリプトを起動(終了を待たない)、プロセスIDを保持させる →各停止ボタンを作成し、そのイベントで割り当てられたプロセスIDをKILL それ以外となると即時終了はなかなか難しいと思います。 ただ確実性という意味で対応するのであれば、簡単な例で考えると Set ws = WScript.CreateObject("WScript.Shell") Set prs = ws.Exec("監視スクリプトpath") ←これで監視スクリプトを起動する MsgBox prs.ProcessID ←プロセスIDを把握 それを元にタスクマネージャーでKILL、という方法が考えられますね。

okwavewan
質問者

補足

早速のご返事ありがとうございます。 実は先ほど別件で検索していたところ、偶然にも私と同じ思いから作られた無限ループ終了スクリプトを発見しました。 http://mamac.jpn.ph/mamac/server_13.html これは無限ループ動作で起動したスクリプトを再び起動して、つまり二重起動すると、終了のためのダイアログが現れるというものです。 構造文が長いので短くしようと思いましたが無駄なところはないようでできませんでした。でも、使用感はよいで気に入りました。なんで検索でヒットしなかったんだろう。Reginleif さんにも色々アドバイス頂きありがとうございました。

すると、全ての回答が全文表示されます。
  • Reginleif
  • ベストアンサー率37% (9/24)
回答No.1

Loop処理の中にIf判定でLoop停止処理を入れておくというのも手ですね。 例えばVBScriptの中でファイル(空ファイルでOK)の存在確認を行い 存在するのであればLoop処理を続けない、など。 そうすれば強制終了以外での停止方法が得られますし。 ファイル名をスクリプトに近い、または処理名称で定義しておけば停止スクリプトを間違える、なんてことも減るかと。 参考程度に。 Set objFso = CreateObject("Scripting.FileSystemObject") If objFso.FileExists("c:\vbscript1_break.txt") Then ファイルが存在するのでLOOP処理を抜ける End If Set objFso = Nothing #少し気になったんですが、Loop処理はSleepしてるんですよね…?

okwavewan
質問者

補足

お答えありがとうございます。 ループの回るタイミングは時計に同期したものや、WScript.Sleep、ダイアログの表示時間で変わるもとか色々です。周期も10秒程度からひと月一回まであります。 それで、Reginleif さんのアドバイスによるものと同等(ファイルが見えなくなると強制終了)のものを試したことがあります。しかし、ループの回転が長周期の場合は、ファイルの存在をモニターする地点まで達するのに時間が掛かってすぐ終了できないという欠陥がありました。 10秒周期であっても最悪10秒待たないと終了できない訳で、瞬時に終了できないか考えています。また、すぐ終了したいスクリプトにはメインループの中に高速のループを入れてレスポンスをよくして動かしているものもありますが、スマートでなく負荷も余分に掛かって気に入りませんです。 今思いつくのはプロセスIDですが、スキルがなくてだめです。

すると、全ての回答が全文表示されます。

関連するQ&A