プロが教える店舗&オフィスのセキュリティ対策術

https://oshiete.goo.ne.jp/qa/8952035.html
前回質問では、shell実行した後待機、終了後に次行へうつりました。これを変更し、shell実行後は別なvba処理をしつつ終了監視し、終了したら別のshellを実行したいのです。

どうすればいいでしょうか?

質問者からの補足コメント

  • ありがとうございます。
    動作のしくみは以下のものでいいでしょうか?
    電卓に限らずプログラムを起動すればプロセスIDを得られ、TaskEndを時々動かしてプロセスIDが稼働中かどうか調べ、プロセスIDが消失していたらプログラムが終了したと判る。RunスクリプトではプロセスIDを得られないため、Runで用意されている待機のみとなる。

    No.1の回答に寄せられた補足コメントです。 補足日時:2015/04/02 23:00

A 回答 (3件)

追伸


https://msdn.microsoft.com/ja-jp/library/cc42911 …
からの抜粋ですが
『戻り値
関数が成功すると、0 以外の値が返ります。
関数が失敗すると、0 が返ります。拡張エラー情報を取得するには、 関数を使います。』
なので#1の回答はあまり良くありません。
ProcessID(終了しているのでProcessIDは存在しない)を渡して0が帰ってくれば終了していると
考えたのですが・・・エラーになる場合は他にもあるでしょうから。。。
下記に差し替えを

Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
ByVal dwProcessID As Long) As Long
Private Declare Sub CloseHandle Lib "KERNEL32.DLL" (ByVal dwProcessID As Long)
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const STILL_ACTIVE = &H103

Function TaskEnd(ByVal dwProcessID As Long) As Boolean
Dim hProcess As Long
Dim lpdwExitCode As Long
Dim retVal As Long
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, True, dwProcessID)
retVal = GetExitCodeProcess(hProcess, lpdwExitCode)
Call CloseHandle(hProcess)
TaskEnd = Not (lpdwExitCode = STILL_ACTIVE)
End Function

Sub test()
Dim dwProcessID As Long
dwProcessID = Shell("C:\Windows\System32\calc.exe", 1)
MsgBox TaskEnd(dwProcessID)
Stop '電卓を閉じてください
MsgBox TaskEnd(dwProcessID)
End Sub
    • good
    • 0

はい、そういう理解で良いと思います。


重複するProcessID が同時に存在することは無いので
これを手がかりに調べることになります。
    • good
    • 0
この回答へのお礼

ありがとうございます。
引き続き勉強します。

お礼日時:2015/04/03 19:57

VBA はマルチタスクの処理は出来ませんので


『しつつ』は無理かと。
逐一チェックして進めるか・・ぐらいでは。
sub test を実行してみてください。Calc.exe のパスが違うかも?
以下、標準モジュールにて。

Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
ByVal dwProcessID As Long) As Long
Private Declare Sub CloseHandle Lib "KERNEL32.DLL" (ByVal dwProcessID As Long)
Private Const PROCESS_QUERY_INFORMATION = &H400

Function TaskEnd(ByVal dwProcessID As Long) As Boolean
Dim hProcess As Long
Dim lpdwExitCode As Long
Dim retVal As Long
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, True, dwProcessID)
retVal = GetExitCodeProcess(hProcess, lpdwExitCode)
Call CloseHandle(hProcess)
TaskEnd = (lpdwExitCode = 0)
End Function

Sub test()
Dim dwProcessID As Long
dwProcessID = Shell("C:\Windows\System32\calc.exe", 1)
MsgBox TaskEnd(dwProcessID)
Stop '電卓を閉じてください
MsgBox TaskEnd(dwProcessID)
End Sub

なお、長い処理時間のコード実行中に
別のプログラムなどを立ち上げた時にすでに閉じたプログラムと
同じProcessID が再度振り当てられる可能性については不明です。
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!