掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
厳密にアプリケーションの終了状況を把握するには? (ID:84745)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
ご回答ありがとうございます。 >そのプロシージャの続行は停止しますが、アプリケーション自体は >引き続き操作可能です。 本当ですね。何も調べずに書いてしまってすみません。アプリケーションは呼び出したプロシージャ以外、止まりませんでした。とても魅力的な解決策と思ったのですが、当方の勝手な事情により、これだけでは埒があきませんでした。このような当方の事情は初めに細かく言っておくべきだったと反省しております。実は、タイマーを用いてある一定間隔ごとにチェックするアプリケーションの一部だったのですが、一定時間が経った後にチェックして条件が合えば、他のアプリケーションを起動して、条件が合わなかったら再びタイマーで一定時間ごとのチェックを繰り返すという動作を実現したかったのです。そして、再びチェックして条件が合えば、再び他のアプリケーションを起動するのですが、このときに既に他のアプリケーションが起動されている場合は、起動の処理を行わないようにするために、既に起動した他のアプリケーションの終了状況をチェックしたかったのです。このため、ただ単純に「魔界の仮面弁士」さんから教えていただいたWScript.Shell.Runを用いた同期起動をタイマーの中に組み込むだけでは、呼び出したプロシージャが止まってしまうのでその後のタイマーによるチェックが出来ないという状態になってしまいました。当たり前といえば当たり前のことなのですが、WScript.Shell.Runを呼び出したプロシージャは止まっていて、なおかつ、そのプロシージャを呼び出しているタイマーは止まらないというような、このようなわがままなことは出来ますでしょうか。具体的なコードを示しておきました。 Private Sub Timer1_Timer() Dim L As Long With CreateObject("WScript.Shell") List1.AddItem Format(Now(), "hh:nn:ss YYYY-MM-DD") _ & " : Start 'CALC.EXE'" L = .Run("CALC.EXE", vbNormalFocus, True) List1.AddItem Format(Now(), "hh:nn:ss YYYY-MM-DD") _ & " : End 'CALC.EXE' (0x" & Right("00000000" & Hex(L), 8) & ")" End With DoEvents End Sub この状況を打開すべく、イメージ的に考えてみると、タイマーから呼び出されたTimer1_Timer()プロシージャには、そのプロシージャ内のプログラムを実行する1つの制御子のようなものが渡されて(あまりうまく表現できないのですみませんが、「プログラムを実行できるもの」のようなものを制御子と考えて)、この制御子がプロシージャ内の上から下へプログラムを順番に消化していき、WScript.Shell.Runを呼び出す手前で、この制御子を2つに分けて、1つはWScript.Shell.Runの処理を飛ばしてその次の処理へ行きTimer1_Timer()プロシージャを終了する制御子と、もう1つはWScript.Shell.Runを実行して他のアプリケーションを起動し、アプリケーションの終了まで待機していて、他のアプリケーションが終了してWScript.Shell.Runメソッドの呼び出しが終わったらこの制御子は消滅するような、なんとも無理やりで分かりにくい表現で申し訳ありませんが、このようなことが出来ればタイマーも止まらずに、終了状況も確実にチェックできると思いました。しかし、実際に、制御子を2つに分けるということや、制御子が消滅するなどということが出来るのかどうか、私は実現するすべも思いつきません。あたたかくご回答していただいている皆様に、私が思いつきで名付けた「制御子」を分かっていただけていないのかもしれません。本当にアマチュアな意見で申し訳ありません。「も」さんから以前、「スレッドで管理」と言われましたけれど、制御子を2つに分けるということが「スレッドで管理」することなのだろうかとも考えました。 この解決策を用いるなら、WScript.Shell.Runメソッドを使うので、Windows Scripting Hostの機能を使うということですよね。WSHはWindows98から標準装備とあったのですが、WindowsNTは4.0から標準装備なのでしょうか。 「魔界の仮面弁士」さんから教えていただいたソースコードでWScript.Shell.Runメソッドを用いて他のアプリケーションを起動させてみました。「計算機」が起動されて、「計算機」を終了させるとリストに終了表示が出ました。 ①そこで、ためしに、起動した「計算機」を、「×」をクリックして閉じるのではなくて、強制終了させてみると、リストに終了表示が出ませんでした。そして、起動する側のアプリケーションも終了しようとして「×」をクリックするとウィンドウは消えるのですが、まだアプリケーションは実行している状態で残ってしまいました。 ②次に、WScript.Shell.Runメソッドを用いて他のアプリケーションを起動して、そのまま、他のアプリケーションの終了を待たずに、起動した側のアプリケーションを「×」をクリックして閉じようとすると、ウィンドウは消えるのですが、この場合も、まだアプリケーションは実行している状態で残ってしまいました。 私の実現しようとしているアプリケーションでは、上のどちらの場合もありうることなので、アプリケーションが終了出来ずに実行している状態のまま残ってしまうのはあまりうれしくありません。 Private Sub Form_Unload(Cancel As Integer) End End Sub このようにしてEndをいれると、②の方は、他のアプリケーションの終了とともに終了しましたが、①の方は実行している状態のまま残ってしまいました。同期起動をさせようとすると、必ずこのような終了に関する問題が出てきてしまうなら、同期起動は止めようかとも考えているのですが、これを回避できるよい案がありましたら、ご教授お願いします。 >INFINITEだと、相手が終了するまで、こっちは何もできなくなってしまうので、 >短めのタイムアウト時間を設定しておき、タイムアウト時にはDoEventsを >呼び出すようにしてみてください。 この方法を用いると、WaitForSingleObjectを短めのタイムアウト時間で呼び出して、タイムアウト時にDoEventを呼び出すという処理をDo...Loopで反復して、監視するということになりますよね。GetExitCodeProcessで終了チェックすることと動作的には同じことになるのかなと思います。 Do...Loopで反復して監視すると、当方の事情でタイマーから呼び出しをしているので、ここでも、Do...Loop反復の監視に入ってしまうと、Do...Loopに制御を奪われて、タイマーが一定時間ごとにチェックするということが出来なくなってしまうので、Do...Loop反復の監視と、タイマーの作動が同時に出来れば、WaitForSingleObjectやGetExitCodeProcessで監視する方でもよさそうです。
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.