アプリ版:「スタンプのみでお礼する」機能のリリースについて

既存のbatファイルが存在し、C#プログラムより、実行結果コ-ドを取得したいのですが、どうやっても「0」が帰ってきましまい、悩んでいます。 よいアドバイス&指摘を下さい。

<batファイル>
 @echo off
 set RET_CODE=%1
 echo %RET_CODE%
 exit /b %RET_CODE%

<C#プログラム>
 ProcessStartInfo psInfo = new ProcessStartInfo();
 psInfo.FileName = @"D:/app/Send.bat";
 psInfo.Arguments = "45";
 psInfo.CreateNoWindow = true;
 psInfo.UseShellExecute = false;
 psInfo.RedirectStandardOutput = true;
 Process ps= Process.Start(psInfo);
 string st = ps.StandardOutput.ReadToEnd(); ← 何も出ない?
 ps.WaitForExit();
 string rt = ps.ExitCode.ToString(); ← 必ず「0」が返却?

A 回答 (3件)

追記の追記。



psInfo.FileName = @"D:/app/Send.bat";
psInfo.Arguments = "45";
と書くと、実は
psInfo.FileName = @"C:\WINDOWS\SYSTEM32\CMD.EXE";
psInfo.Arguments = @"D:/app/Send.bat 45";
と言うように「CMD.EXEが起動するように、Windowsが小細工をする」のです。

そのため、Send.batは「子プロセスのCMD.EXEが実行」します。

その為
exit /b 終了コード
と書くと、この終了コードは「子プロセスとして動いているCMD.EXEのERRORLEVELになるだけで、CMD.EXEの終了コードにはならない」のです。

そして、Send.batを実行し終わった子プロセスのCMD.EXEは「これ以上、もう、何もする事がなく、正常終了してしまう」ので「正常終了時の終了コードとして0で終了」します。

終了コードが0で終了すれば、当然
ps.ExitCode
の値は「常に0」です。

そういう訳で「子プロセスとして動いているCMD.EXEを終了させ、終了コードを持たせる」には
exit 終了コード
と書いて「/b無しのexitコマンドを実行」しなければなりません。

こうすれば「Send.batを起動した子プロセスのCMD.EXEの終了コードが、exitコマンドで指定した値になる」のです。

exitコマンドで指定した値が終了コードになれば、当然
ps.ExitCode
の値も「引数で渡した値」になります。

この回答への補足

何度も丁寧なご説明ありがとうございます。
ご指摘の通り「/b無しのexitコマンドを実行」すれば、処理結果コ-ドを取得することができました。

実は、既存で存在する「batファイル」が、「/b付きのexitコマンドを実行」しているため、今回の問題に直面しましたが、実際のところ、そのbatファイルを使用しているのかが、不確実なため困っております。

最後のご回答にあります「CMD.EXEが起動するように、Windowsが小細工をする」の箇所ですが、逆に「小細工をさせない」方法はあるのでしょうか?

補足日時:2009/12/04 17:29
    • good
    • 0
この回答へのお礼

しばらく、「補足に対する回答がいただけるかな?」と待っておりましたが、反応がないようですので、これにて完了にさせていただきます。
あいがとうございました。

お礼日時:2009/12/17 17:11

追記。



EXIT /B 終了コード

EXIT 終了コード
の違いが良く判らないと言う場合は、以下の検証を行ってみて下さい。

---------main.bat
CMD /c sub1.bat
if ERRORLEVEL 10 echo 10
pause
call sub1.bat
if ERRORLEVEL 10 echo 10
pause
CMD /c sub2.bat
if ERRORLEVEL 10 echo 10
pause
call sub2.bat
if ERRORLEVEL 10 echo 10
pause

---------sub1.bat
exit /b 10

---------sub2.bat
exit /b 10

---------実行結果
C:>main
C:>CMD /c sub1.bat ←別プロセスとしてsub1.batを起動
C:>exit /b 10 ←sub1.batが終了する。子プロセスとして起動したCMDは「もう何もする事がなく、正常終了する」ので終了コードは0
C:>if ERRORLEVEL 10 echo 10 ←main.batのERRORLEVELには値が返らない
C:>pause
続行するには何かキーを押してください...
C:>call sub1.bat ←同一プロセスとしてsub1.batを起動
C:>exit /b 10 ←sub1.batが終了する。「10」はERRORLEVELに渡る
C:>if ERRORLEVEL 10 echo 10 ←main.batのERRORLEVELに値が返る
10 ←10を表示する
C:>pause
続行するには何かキーを押してください...
C:>CMD /c sub2.bat ←別プロセスとしてsub2.batを起動
C:>exit 10 ←子プロセスとしてsub2.batを起動したCMDが終了する。終了コードはexitで指定した10
C:>if ERRORLEVEL 10 echo 10 ←main.batのERRORLEVELに値が返る
10 ←10を表示する
C:>pause
続行するには何かキーを押してください...
C:>call sub2.bat ←同一プロセスとしてsub2.batを起動
C:>exit 10 ←親プロセスとしてmain.batを実行中のCMDが終了する。終了コードはexitで指定した10。ここでDOS窓も閉じてしまい、main.batの続きは実行されない
    • good
    • 0

EXIT /B 終了コード


は、バッチ中に書いた場合「プロセスの終了コードではなく、環境変数ERRORLEVELに指定した値をセットし、バッチのみを終了」します。この時、シェルであるCMD.EXEは終了しませんので、プロセスの終了コードには値が渡りません。

一方、
EXIT 終了コード
は、バッチ中に書いた場合「シェルであるCMD.EXEの終了コードに指定した値をセットし、バッチと一緒にシェルであるCMD.EXEも終了」します。

要は「バッチファイルのexitコマンドに/bを付けたのが悪い」のです。
    • good
    • 0

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A