• ベストアンサー

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

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

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4836/10237)
回答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

  • Win98 + Excel97 + VB での無限ループの強制終了

    表題の件なのですが、 例えばエクセルシートの適当な位置にボタンを配し、以下のようなソースを組んだとします。 Private Sub CommandButton1_Click() s=0 Do While (s<15) s = s + 1 Loop End Sub もしも誤って s=s+1の行をコメントにしたら無限ループとなり エクセル及びVBが【実行中】のまま固まってしまいますよね? この場合「タスクマネージャ」を使って強制終了しています。 当然エクセルもVBもタスクから消滅してしまいます。 ファイルを保存していない時にこの状態になるとかなりブルーです。 作成途中のプログラムを残せるようなプログラムのみ終了させる方法 または 無限ループ内に「ループから強制的に抜け出すようなアクション」の埋め込み方法(または以下の意味は解りますかね…(汗)) 等、ありましたら回答よろしくお願いします。 それともこのような状態になったら「ソースを作ったあなたが悪い!最終保存以降の編集内容はあきらめよ」と言うことなんでしょうか? ちなみに論点はForNext等への変更ではなく あくまで「誤って表記してしまった無限ループからの脱出」です よろしくお願いします。

  • 無限ループで暴走

    自分の力量が足らずしょっちゅうcgiで誤って無限ループを作成し自分のPCの仮想サーバでテスト実行してしまいます 案の定、暴走・・・ Apachi2を終了してもperl.exeが処理を続けていてCPU使用率が100%のままでタスクマネージャーでperl.exeを強制終了しようとしてもアクセス拒否されてしまいます 仕方が無くいつもPCを再起動しいます PCを再起動せずにCPU使用率を下げる方法はありますでしょうか?

    • 締切済み
    • CGI
  • VB上で実行中の無限ループの止め方

    今まで、CUIベースのBASICでのプログラムの経験はあるのですが Visual系のBASICは初心者です。 原因はわかっているのでプログラムの修正はできるのですが VB上でコンパイルして実行したときに無限ループに陥ってしまって どうにもプログラムをとめられなくなります。 そんなことがないように、実行前に全てのプロジェクトを保存して いますので、そんなに実害はないのですが、どうすればとめられるのでしょう・・ 今現在は、タスクマネージャーから強制終了させています。

  • 無限ループ対策

    プログラミングのデバッグ時、無限ループに入ってしまい、プログラムを強制終了することもままならなくなることがあります。 CPUのリソースを完全に使っているために、こちらの入力を受け付けなくなると思うのですが、 マルチCPU環境ではどういった状態になるのでしょうか? 無限ループは起こらないのでしょうか? さらに、デュアルコアCPUの場合はどうなのでしょうか? 無限ループのもどかしさから開放されるならPCを新調しようと思うのですが、 何かご存知の方教えてください。よろしくお願いします。

  • 無限ループ中にある任意のキーを押すと抜けるコードを作りたいのですが・・・(VB6です)

    無限ループを動作中にあるキー(例えば[Ctrl]+[c])を押すと、そのプログラムを抜けて終了するコードを作りたいのですが、どなたかご教授いただけませんでしょうか?

  • WSH(VBScript)でアプリケーションを停止したい

    こんにちは。 OSはWIN2K、WSH5.6を使用しています。 WSH(VBScript)で「c:\abc.exe」という アプリケーションを起動してます。 このアプリケーションは複数起動できな いためパラメータを変え連続3回Runメ ソッドで起動しました。 しかし一番最初に起動したものが落ちて いないため2本目以降は起動しません( 1本終わったら閉じるボタンでそのアプ リケーションを終了させると2本目以降 も起動します)。 タスクマネージャーのプロセスにも abc.exeがでていますので2、3本目の 起動前にこれを停止させるスクリプトを 記述したいのですが、どなたかご教授い ただけますでしょうか。 よろしくお願いいたします。

  • VBAからタスクの終了

    タスクマネージャーのアプリケーションタグにて、 右クリックでタスク終了する操作をエクセルVBAで行いたいのですが可能でしょうか? VBAでWebBrowserを使ってネットにアクセスし、データを取得しているのですが、 たまに「スクリプトエラー」が出て中断してしまいます。 スクリプトエラー画面で「はい」もしくは「いいえ」ボタンをマウスでクリックすれば次に進みますが、 とりあえず、VBAで強制的に画面を消して中断しないようにしたいのです。 スクリプトエラーの消し方を調べてIEの設定をいじっては見たのですが、 たまに発生する傾向は変わりませんでした。 スクリプトエラーはタスクマネージャーのアプリケーションタグには表示されます。 (プロセスタグには表示されません。) ネット検索してみると、プロセス終了はありましたが、タスク終了に相当するものは 見つけられませんでした。 なお、ネット検索でAPIのEnumWindows関数を使ってアプリケーションタグに表示されているものの取得までは わかりましたが、終了させる操作はわかりませんでした。

  • 無限ループでDebug.Writelineしてしまい、VB2005が応用しません(>_<)

    VB2005 ExpressEditionです。 先ほど、間違えて無限ループ内でDebug.Writelineメソッドを使ってしまい、プログラムのデバッグ中止ボタンを押せたにも関わらず、いつまでもイミディエイトウィンドウに文字列がトレースされます。かれこれ30分ぐらい経ってもまだ終わらず、ビジー状態で次の作業に移れません。 プログラムを強制終了するしかないでしょうか? 保存していない変更が破棄されると困るのですが、強制終了しても作業時の状態をを復元する機能などあるでしょうか?

  • 強制終了できないプロセスの強制終了

    異常終了するアプリケーションのプロセスが残ってしまい、 タスクマネージャでの強制終了も受け付けません。 これを強制終了させるにはどうすればよいでしょうか。

  • 無限ループから脱出不可能です

    以下のコードはオフラインでは正常に作動しますが、 一旦 FC2.com にアップロードしたところ、 画像のスクロールが終了したのちに、次のページに移動せずに モデムが急速に信号をダウンロードし始めて、 無限ループに陥った様相を呈したまま、同じ画面でフリーズ状態になってしまいます。 どのような対策をとれば、このような不具合が解消するかを ご指導いただけますでしょうか。 念のため、URL を付け加えておきます。 http://nonprofit4excellence.web.fc2.com/i/images/d002.html <SCRIPT type="text/JavaScript"> var max=1000; var i=1; function winScroll(){ if ( i > max ) { GoNext() ; } else { scroll(i,0); } i++; } function GoNext() { location.href = "d003.html"; } </SCRIPT></head> ***** <body onLoad="setInterval('winScroll()', 7)" > *