- ベストアンサー
shell関数について
毎度、お世話になっています。 現在、C言語で書いた複数のプログラムをBATファイルで処理するように記述しています。VBでその制御を行っているのですが、VBの処理手順として子フォーム(textあり)にデータを書きこんで、ボタンを押すとshellでbatファイルを起動し、バッチファイルの結果として、あるディレクトリにresult.txtが作成され、VBで他の子フォームに読みとらせようとしているのですが、shellだと、実行の終了を待たずに次にいってしまうので、そのバッチファイルの実行処理が終わらず、result.txtの内容を読み込むことができません。 待つようにするにはどうすればよいのでしょうか? ちなみにVBは一週間前にはじめて、自分でも調べてなんとか作ろうとしたのですが、時間がないため、ここに質問させていただきました。なるべく簡単なアルゴリズムで、よろしくお願いします。 VBのプロセス テキストにデータを書き込む ↓ ボタン → テキストの内容を*.txtとして保存 ↓ バッチファイル起動 ↓(ここで右の実行を待たない ↓ ので読み込むことができない) C言語で書かれたプログラム実行 ↓ result.txtを ← 結果としてresult.txtが出来上がる 読み込んで表示
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
あと、拡張エラー情報を取得してどのようなエラーか確認をしてみてください。 APIのヘルプではGetLastError()を使用してと記述されていますが、VBでは、Err.LastDllErrorで取得できます(というか、これで取得しないと違うエラー値が返される可能性があります) http://www.microsoft.com/JAPAN/developer/library/jpwinpf/_win32_waitforsingleobject.htm http://www.microsoft.com/JAPAN/developer/library/jpwinpf/_win32_createprocess.htm
その他の回答 (4)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>ですが、以下のWaitForSigleObjectの返り値がWAIT_FAILEDになって >しまい待機失敗をしていることがわかったのですが、 待機の前にバッチファイルは起動するはずなんですけどね。 ということで、待機に失敗する理由は、おそらくCreateProcessで 起動に失敗したからです。 CreateProcessの戻り値を調べてください。
お礼
お返事が遅れてすみません。 ats8181oyajiさんの方法で一応解決ができました。 しかし、taka_tetsuさんの方法でもやってみようと考えています。原因がわかるまで。。。 言い訳になってしまうかもしれませんが、ちょっと今、非常に忙しい状態で、あと1ヵ月ぐらい続きそうです。なかなかtryする暇がありません。現在、3日に1度は寝ずに研究をやっている状態で偏頭痛まで伴っています。 必ず、結果を書き込みますので、一時の間、締め切らずにこのままにしておきます。私事によってtaka_tetsuさんが気にかけられておられ申し訳ありませんが、その旨よろしくお願いします。
- BlueRay
- ベストアンサー率45% (204/453)
お馬鹿な手法です。参考にもならないかも・・・ 1.ボタンを押されたタイミングで、システム日時を取得→sDate 2.指定ファイルの更新日付を取得 (毎回ファイルを新規で作成するなら、ファイルの有無のチェックで良いと思う) 3.sDateより大きくなっていたら、更新済みなので4番へ そうでないなら、また2番へ ※条件が一致するまで2・3を繰り返す。そのときに待ち時間を入れたり 画面がロック状態にならないようにする必要はあると思います。 4.ファイルより内容の取得 こんな流れでは、如何でしょう?。
お礼
う~ん試していないのでわからないのですが、処理が終わるまで、適当な処理を行うループをさせていたのですが、動作が極端に鈍くなってしまいました。 様様な面でBlueRayさんが提案してくれた方法を試してみたいと思います。 ありがとうございました。
- ats8181oyaji
- ベストアンサー率38% (94/244)
こんにちは 私はこの方法で待機しています。 ソースをそのままコピーします。 .bas '* Shell起動プロセスとの同期 'Shell起動プロセスのオープン(状態の取得準備) Public Declare Function OpenProcess Lib "KERNEL32" _ (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _ ByVal dwProcessId As Long) As Long 'Shell起動プロセスとのシンクロ(待機する) Public Declare Function WaitForSingleObject Lib "KERNEL32" _ (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long 'Shell起動プロセスのクローズ(終了) Public Declare Function CloseHandle Lib "KERNEL32" _ (ByVal hObject As Long) As Long 'Shell起動プロセスが実行中か調べる(状態の取得) Public Declare Function GetExitCodeProcess Lib "KERNEL32" _ (ByVal hProcess As Long, lpExitCode As Long) As Long Public Const SYNCHRONIZE = &H100000 Public Const INFINITE = &HFFFF .frm IDProcess = Shell("command.com /c " 実行プログラム) hProcess = OpenProcess(SYNCHRONIZE, 1, IDProcess) 'SYNCHRONIZE = &H100000 ret = WaitForSingleObject(hProcess, INFINITE) 'INFINITE = &HFFFF ret = CloseHandle(hProcess) ちょっと長いですけど。頑張ってください
お礼
ありがとうございます。 何の作業を行っているか、わかりませんが できました 。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
お礼
情報ありがとうございました。 しかしエラーが発生してバッチファイルが動作しません。 デバッグをかましてどこでプログラムが停止しているのか見たので ですが、以下のWaitForSigleObjectの返り値がWAIT_FAILEDになって しまい待機失敗をしていることがわかったのですが、 udtProcessInfomation.hProcessが何の情報を表しているのかや、何が 間違っているのかわからずお手上げ状態です。 もし、御分かりになられるようでしたら、よろしくお願いします。 lngWaitForObjectEvent = _ WaitForSingleObject(udtProcessInfomation.hProcess, _ lngWaitForObjectTimeOut) With Label4 ' 待機結果を表示 Select Case lngWaitForObjectEvent Case STATUS_WAIT_0 .Caption = "プロセスは終了" Case WAIT_TIMEOUT .Caption = "待機はタイムアウト" Case WAIT_FAILED .Caption = "待機は失敗" End Select
お礼
お礼が遅くなってすみません。 もう一度、taka_tetsuさんの方法で組み直してバッチファイルの操作を行いました。結果として正常に動作しました。 エラーが出ていた時のプログラムはNo2さんの方法で上書きしてしまって、 結局、何が悪かったが分からなかったのですが。。 ちょっと釈然とせず、すみません。 taka_tetsuさんの意見を今後の参考とさせてもらいます。 ありがとうございました。