掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
厳密にアプリケーションの終了状況を把握するには? (ID:84746)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
> WScript.Shell.Runを呼び出したプロシージャは止まっていて、なおかつ、 > そのプロシージャを呼び出しているタイマーは止まらないというような、 『一定間隔ごとに(何かを)チェックするタイマープロシージャ』と、 『WshShell.Run を呼び出すタイマープロシージャ』を分けるとか。。。 > WindowsNTは4.0から標準装備なのでしょうか。 NT4用のWSHは、Windows NT Option Packに含まれています。 > WScript.Shell.Runメソッドを用いて他のアプリケーションを起動させてみました。 > 「計算機」が起動されて、「計算機」を終了させるとリストに終了表示が出ました。 ここでいう『計算機』という言葉は、先のサンプルで使ったcalc.exe(電卓)、 すなわち、「Runメソッドにより実行された他のアプリケーション」の事を 指しているのでしょうか? > 強制終了させてみると、リストに終了表示が出ませんでした。 「終了表示が出なかった」という事は、そのアプリが終了していない可能性も考えられます。 ちなみに当方では、Runメソッドで起動したアプリを[×]ボタンで閉じた場合も、 タスクマネージャから強制終了した場合も、呼び出し側の動作に変化はありませんでした。 > 起動する側のアプリケーションも終了しようとして「×」をクリックすると > ウィンドウは消えるのですが、まだアプリケーションは実行している状態で残ってしまいました。 コーディングに問題が無いか、確認してみてください。 御存知とは思いますが、VB6では、フォームのプロパティやメソッド、 あるいはコントロール等にアクセスすると、そのフォームは自動的に Loadされる事になります。 http://www.gj.il24.net/~nakasima/vb/tech/end/index.htm たとえば、以下のようなコードを考えてみて下さい。 Option Explicit Private Sub Command1_Click() Dim S As String S = CStr(CreateObject("WScript.Shell").Run("CALC.EXE", vbNormalFocus, True)) List1.AddItem S '……★ MsgBox "表示中のフォーム数=" & CStr(DoEvents()) & vbCrLf & _ "ロード中のフォーム数=" & CStr(Forms.Count) End Sub Private Sub Form_Load() Debug.Print "Load" End Sub Private Sub Form_Unload(Cancel As Integer) Debug.Print "Unload" End Sub このコードにて、 1. ボタンを押下して、電卓を起動させる。 2. 電卓を起動したまま、フォームを閉じる。 3. その後、電卓を閉じる。 という処理を行った場合について考えてみますと…… この場合、2の処理(フォームを閉じる)で Unload イベントが実行されますが、 続く3の処理(電卓終了)では、Runメソッドの続きが実行され、★の行にて、 「List1」という『フォームのコントロール』にアクセスする事になります。 この時点で、Form1は自動的に再ロードされるため、プログラムは終了しません。 この問題を解決するには、以下のようにします。 Option Explicit Private mIsLoaded As Boolean Private Sub Command1_Click() Dim S As String S = CStr(CreateObject("WScript.Shell").Run("CALC.EXE", vbNormalFocus, True)) If mIsLoaded Then List1.AddItem S End If MsgBox "表示中のフォーム数=" & CStr(DoEvents()) & vbCrLf & _ "ロード中のフォーム数=" & CStr(Forms.Count) End Sub Private Sub Form_Load() mIsLoaded = True Debug.Print "Load" End Sub Private Sub Form_Unload(Cancel As Integer) Debug.Print "Unload" mIsLoaded = False End Sub > このようにしてEndをいれると 正常な終了処理の阻害となるので、可能な限り、Endは使わない事をおすすめします。 もし、上記コードで、Unload 時に End を使った場合、 S = CStr(CreateObject("WScript.Shell").Run("CALC.EXE", vbNormalFocus, True)) の部分は、Runメソッド完了後の処理が打ち消されてしまいます。 (「変数 S への代入」や「CStr関数の実行」さえ行われません) > (1)の方は実行している状態のまま残ってしまいました。 こちらでは再現できないので、判断しかねますが、やはり、呼び出したプログラムの 「強制終了」に失敗しているような気がします。 呼び出したプログラムが生存中だとすれば、Runメソッドが終了せず、すなわち、 「リストに終了表示が出ない」結果となり、ひいては、呼び出し側プログラム自体が 実行中のままになってしまう事も説明が付きますので。 > GetExitCodeProcessで終了チェックすることと動作的には同じことになるのかなと思います。 GetExitCodeProcessには、以下のような問題があります。 http://nienie.com/~masapico/doc_AppExec.html また、タイムアウト設定無しで、即座に結果を返してしまうため、ループの 実行回数が多くなり、CPU負荷も高くなります。 替わりに、先に回答した MsgWaitForMultipleObjects APIを試してみてください。 こちらであれば、INFINITEで待機しつつ、かつ、マウスやキーボード等の処理を 割り込ませるようなコーディングも可能かと思います。(試していませんけれども) # 以下は、MsgWaitForMultipleObjects のサンプルです。 # VBのコードではありませんが、処理の概要はつかめるでしょう。 # http://homepage2.nifty.com/Mr_XRAY/Halbow/Notes/N001.html
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.