掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
厳密にアプリケーションの終了状況を把握するには? (ID:84747)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
ご回答ありがとうございます。 >『一定間隔ごとに(何かを)チェックするタイマープロシージャ』と、 >『WshShell.Run を呼び出すタイマープロシージャ』を分けるとか。。。 そうですよね。簡単に実装できますし、2つのタイマーで別々に動かせば、実現できることでしたよね。何か難しく、ことを考えていました。タイマーを2つ使って別々に監視しようと思います。こうすると、ご教授いただいたWshShell.Runを使用して終了を監視することも出来ますし、MsgWaitForMultipleObjectsを使用して終了を監視することも出来ますし、ことが簡単に進みました。 >ここでいう『計算機』という言葉は、先のサンプルで使ったcalc.exe(電卓)、 >すなわち、「Runメソッドにより実行された他のアプリケーション」の事を >指しているのでしょうか? その通りです。計算機でなく電卓の誤りでした。すみません。 >御存知とは思いますが、VB6では、フォームのプロパティやメソッド、 >あるいはコントロール等にアクセスすると、そのフォームは自動的に >Loadされる事になります。 WshShell.Runで同期起動させてから、起動した側のアプリケーションの方が早く終了しても、その後、他のアプリケーションが終了してから、WshShell.Runから後のプロシージャ内のプログラムは実行されるのですね。なので、List1のメソッドが実行されて、フォームが非表示でロードされて終了しないということですね。納得しました。 >正常な終了処理の阻害となるので、可能な限り、Endは使わない事をおすすめします。 はい。なるべく使わないようにしています。 >GetExitCodeProcessには、以下のような問題があります。 >http://nienie.com/~masapico/doc_AppExec.html 知りませんでした。CreateProcessで起動させると同時にプロセスのオープンとプロセスハンドルの取得をしておいて、MsgWaitForMultipleObjectsで終了を監視しながら、メッセージを同時に処理して固まらないようにするという方法は、ずいぶん勉強になりました。ただ、コードを見ていて不思議に思うところが1つありました。コードがDelphiであまりなれていないので、重要な構文を見落としているのかもしれませんが、ご教授いただいたhttp://homepage2.nifty.com/Mr_XRAY/Halbow/Notes/N001.html ページの下の辺りのサンプルコード内で、 repeat ret := MsgWaitForMultipleObjects(1, { 1 handle to wait on } processHandle, { the handle } False, { wake on any event } INFINITE, { wait without timeout } QS_PAINT or { wake on paint messages } QS_SENDMESSAGE { or messages from other threads } ); if ret = WAIT_FAILED then Exit; { can do little here } if ret = (WAIT_OBJECT_0 + 1) then begin { Woke on a message, process paint messages only. Calling PeekMessage gets messages send from other threads processed. } while PeekMessage(Msg, 0, WM_PAINT, WM_PAINT, PM_REMOVE) do DispatchMessage(Msg); end; until ret = WAIT_OBJECT_0; とあるのですが、MsgWaitForMultipleObjectsはINFINITEを指定しているので、MsgWaitForMultipleObjectsから以降のプログラムは実行されずにMsgWaitForMultipleObjectsでプログラムが止まってしまって、ずっと待ちつづけてしまうのではと思いました。ここで止まると、その後のメッセージ処理PeekMessageとDispatchMessageは実行されずに固まってしまいますよね。しかし、repeat〜untilで処理が繰り返しになっていますし、MsgWaitForMultipleObjectsはINFINITE指定なのに、処理を次へ渡してしまうのでしょうか。少し疑問に思いました。 >替わりに、先に回答した MsgWaitForMultipleObjects APIを試してみてください。 教えていただいたCreateProcessとMsgWaitForMultipleObjectsで、タイマーを2つ用いて、厳密に終了を監視することにします。 前回の私の回答で、「制御子」などと訳の分からないことを言っておりましたが、スレッドのことでした。そして、スレッドについて調べていったところ、CreateThreadでスレッドが作成できるということが分かりました。サンプルも見つかって http://www.geocities.co.jp/SiliconValley-Cupertino/5872/DownLoad/ http://www.geocities.co.jp/SiliconValley-Cupertino/5872/DownLoad/CreateThread.lzh を参考にして同じようにプログラムして実行したのですが、CreateThreadは恐ろしい関数ですね、コンピュータ自体が復帰不能になってしまいました。何度も少しずつプログラムを書きかえていくと以下の2つについてうまくいきませんでした。スレッドを2つにすればタイマーを2つ用意することと同じことができそうなので、終了の監視に直接関係があるものではありませんが、どうかご教授お願いします。 1.サンプルのコード内のModule1中です。 Public Sub What_Time_is_it_now() Do While bFlag = True Form1.Label1.Caption = Now Loop End Sub という部分で、Sleepをいれて Public Sub What_Time_is_it_now() Do While bFlag = True Form1.Label1.Caption = Now Sleep 200 Loop End Sub のように書きかえると、「×」をクリックしてプログラムを終了する際に強制終了になってしまいます。新しいスレッド内ではSleepは使えないのでしょうか。 2.CloseHandleを呼び出してスレッドを終了していますが、この呼び出しをCommand1_Click()内からではなくて、What_Time_is_it_now()内から呼び出そうとして Public Sub What_Time_is_it_now() Do While bFlag = True Form1.Label1.Caption = Now Loop Call CloseHandle(Form1.hThread) End Sub のように書きかえました。hThread変数は、Form1フォーム内のDim宣言から同じForm1フォーム内のPublic宣言へ書きかえました。このようにすると正常に終了するのですが、 Public Sub What_Time_is_it_now() Do While bFlag = True Form1.Label1.Caption = Now Loop Call CloseHandle(hThread) End Sub のように書きかえて、hThread変数は、Form1フォーム内のDim宣言からModule1モジュール内のPublic宣言へ書きかえました。このようにするとスレッド終了時に強制終了になってしまいました。変数の宣言場所を変えただけなのですが、終了が正常に出来たり、強制終了になったりします。「ここがいけない」というポイントが見当たらないのですが、いけない点がありますでしょうか。
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2020 Takeshi Okamoto All Rights Reserved.