none
【プロセス監視】バッチファイルの処理の終了を待つコードの書き方について RRS feed

  • 質問

  • お世話になります。VC++6.0 OS:Windows2000 MFC,ダイアログベースでアプリケーションを作成しています。

    初心者なので教えて頂きたい事があります。

    【概要】

    表記について、あるバッチファイルの実行をプログラムの中で作成して、そのバッチファイルの処理が終了したら、次のバッチファイルを自動的に実行するような処理を書きたいです。

    【バッチファイルの内容】

    1) バッチファイルをマウスでダブルクリックすると一瞬だけコマンドプロンプトが表示された後、すぐに消え、ある

      実行ファイル(exe)を実行して、内部で3つのファイル(.txt)を作成後、出力します(5秒くらいかかります)

      ※実行ファイルは、バッチファイルと同じフォルダ内にあります。

    2) 1のようなバッチファイルが複数あり、今まではバッチファイルを1つずつ叩いて実行していました。

    【自分でやってみた事】

    1) ShellExecute というファイルを実行させる関数があることを知り、使ってみました。

     バッチファイルは実行できたのですが、処理が 終わった事を判断できないみたいで、単純にバッチファイルを引数で渡 した ShellExecute を2行書いたら、1つ目のバッチファイルだけ実行されて、2つ目のバッチファイルは実行されませんでした。

    2) CreateProcessという関数があることを知り使ってみました。

    この関数は、バッチファイルが終了したことを判断できそうであることが調べてみてわかり、引数にバッチファイル名を設定して実行してみました。

    結果は、コマンドプロンプトの黒い画面は一瞬でてくるのですが、肝心の3つのファイルが出力されませんでした。

    ↑この原因が今、どうしてもわからずに困っています。

    引数に、バッチファイルではなく、メモ帳(notepad.exe)やコマンドプロンプト(cmd.exe)などを試しに渡してみて実行させると、ちゃんとこれらのファイルが実行されます。

    なのに、なぜバッチファイルだと中のEXEが実行されないのかがわかりません。

    【ソースコード】 ※ CreateProcess で作成しています

    // バッチファイル作成ボタン

    void CTestDlg::OnBtnClick()
    {

       PROCESS_INFORMATION pi;
       STARTUPINFO si;

       ZeroMemory(&si,sizeof(si));
       si.cb=sizeof(si);

       if(CreateProcess(NULL, "c:\\test.bat", 

             ,NULL, NULL

             ,FALSE, NORMAL_PRIORITY_CLASS

             ,NULL, NULL

             ,&si, &pi ))

       {

             WaitForSingleObject(pi.hProcess, INFINITE);
             CloseHandle(pi.hProcess);
             CloseHandle(pi.hThread);

         }

    }

     

    2011年8月29日 6:05

回答

  • Windowsが実行できるプログラムは EXE 形式だけであり、BAT 形式は実行できません。そのことはCreateProcess()にも書かれています。

    To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following arguments: /c plus the name of the batch file.

    説明をちゃんと読みましょう。

    • 回答としてマーク 山本春海 2011年9月12日 7:42
    2011年8月29日 6:45

すべての返信

  • Windowsが実行できるプログラムは EXE 形式だけであり、BAT 形式は実行できません。そのことはCreateProcess()にも書かれています。

    To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following arguments: /c plus the name of the batch file.

    説明をちゃんと読みましょう。

    • 回答としてマーク 山本春海 2011年9月12日 7:42
    2011年8月29日 6:45
  • ご回答いただきありがとうございます。

    CreateProcess は、batファイルを直接渡せない事を確認いたしました。

    では、CreateProcess の第1引数に、実行ファイルのフルパスを、第2引数にコマンドライン引数(別のファイル)

    を渡して作成すればよいと思ったのですが、もともとバッチファイルで渡していた↓別のファイル(hikisuu.xxx)を

    以下のように作り直して実行してみたのですが、batTest .exeがコマンドプロンプトで起動して、hikisuu.xxxを

    手入力で指定するような画面になってしまいます。

    CreateProcess("c:\\batTest .exe", "c:\\hikisuu.xxx",NULL,NULL, ・・・

    これを、CreateProcessから、1度で実行する方法などはございますでしょうか。

    // ↓実行していたバッチファイルの中身です(拡張子(.xxx)は独自の拡張子です)

          hikisuu.xxx の中にはさらに別のファイルが指定してあります。

    .\exe\batTest < hikisuu.xxx

    2011年8月29日 8:00
  • 説明をちゃんと読みましょう。
    2011年8月29日 8:06
  • 佐祐理さんがおっしゃっているように、CreateProcessではexe形式の実行ファイルでのみプロセスを作成します。
    一方、ShellExecuteは、簡単に言うとエクスプローラでファイルをダブルクリックするのと同じように動いてくれます(そのため、OSで関連付けられているファイルに関しては、関連付けされたexeがそのファイルを開いてくれている、というわけです)。
    かなり端折った説明ですが…^^;

    たとえば、txtファイルをShellExecuteで開くと、OSで設定を変更していなければメモ帳、つまりは「notepad.exe」で開きますよ。
    これをCreateProcessで開きたい場合、「notepad.exe」で「xxxx.txt」を開くようにしてあげればいいわけです。

    ではバッチファイルの場合は…もうわかりますよね?
    「cmd.exe」から開いてあげればいいわけです。

    バッチファイルの内容が複雑ではないのであれば、それぞれのexeをCreateProcessしてもよいのでは?とも思いますけど…。

    2011年8月30日 3:22
  • // ↓実行していたバッチファイルの中身です(拡張子(.xxx)は独自の拡張子です)

          hikisuu.xxx の中にはさらに別のファイルが指定してあります。

    .\exe\batTest < hikisuu.xxx

    バッチファイルの中に書かれている記述の意味をきちんと理解しているかと言う部分もあると思います。

    書かれている内容だとbatTest.exeに引数としてhikisuu.xxxを渡していると言う記述になっていません。
    もし、この記述を見て引数として渡していると判断したのであれば、バッチファイルの記述とかコマンドラインでの記述方法について
    きちんと確認されることをお勧めします。

    何事も基本が大事ですので小さい事からコツコツと確実に積み上げるようにした方が良いと思います。

     


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2011年8月30日 7:36
  • >CreateProcess("c:\\batTest .exe", "c:\\hikisuu.xxx",NULL,NULL, ・・・

    この行ですが、よく見ると「batTest」と「.exe」の間に「スペース(=0x20)」が
    入っているようです。実際に実行したものも確認してみてはどうでしょう。


    2011年8月30日 8:09
  • ここのフォーラムの趣旨から、外れますが、

    もしかして、複数のバッチファイルを連続して実行したいと言う事でしょうか?

    それならば、わざわざプログラムを書かなくても、バッチファイルの中で、バッチファイルの連続実行するだけではないでしょうか?

    ただ、バッチファイルの中から別のバッチファイルを呼び出すと鉄砲玉で帰ってきませんので、

    CALL コマンドを使うとか、 cmd.exe /C でバッチファイルを呼び出す必要があります。

     (使い方は、コマンドプロンプトで、 CALL /? または cmd /?)

    やりたい事が違っていたら、ごめんなさいです。

     


     

    2011年8月30日 14:31