既存の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」が返却?
No.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が小細工をする」の箇所ですが、逆に「小細工をさせない」方法はあるのでしょうか?
しばらく、「補足に対する回答がいただけるかな?」と待っておりましたが、反応がないようですので、これにて完了にさせていただきます。
あいがとうございました。
No.2
- 回答日時:
追記。
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の続きは実行されない
No.1
- 回答日時:
EXIT /B 終了コード
は、バッチ中に書いた場合「プロセスの終了コードではなく、環境変数ERRORLEVELに指定した値をセットし、バッチのみを終了」します。この時、シェルであるCMD.EXEは終了しませんので、プロセスの終了コードには値が渡りません。
一方、
EXIT 終了コード
は、バッチ中に書いた場合「シェルであるCMD.EXEの終了コードに指定した値をセットし、バッチと一緒にシェルであるCMD.EXEも終了」します。
要は「バッチファイルのexitコマンドに/bを付けたのが悪い」のです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Excel(エクセル) フォルダ内のワードファイルをPDFに一括変換するVBA 3 2023/06/09 16:51
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Visual Basic(VBA) 貼り付けた値が消えていく 以下はソースファイルの2番目のシートのB6から最終行を取得 ターゲットファ 2 2023/07/27 12:23
- その他(プログラミング・Web制作) フォルダ内の特定 拡張子のファイルを一括実行するBat ファイルについて 4 2022/04/17 09:51
- Visual Basic(VBA) エクセルのマクロを使ってメールを送る方法について教えてください 2 2022/03/29 01:36
- Visual Basic(VBA) excel vbaでvlooupの変数がわかりません。 7 2022/05/30 09:35
- Excel(エクセル) エクセル2019でPDFファイル名に枝番号をつけたい。 アクティブワークシートを印刷した後の処理とし 4 2023/06/06 21:00
このQ&Aを見た人はこんなQ&Aも見ています
-
外出時に「待たせる妻」vs イライラする「待つ夫」は日本だけ?見習いたい海外事情
夫の家事参加に積極的なイメージのある海外でも、同様の事例はあるのか。結婚カウンセラーの佐竹悦子さんに伺ってみた。
-
C# Process.Startメソッドで複数引数を渡したい
その他(プログラミング・Web制作)
-
Process.Startの戻り値を後で取得
Microsoft ASP
-
コマンドプロンプトの「%1」と「%~1」の違いがわからない
その他(プログラミング・Web制作)
-
-
4
C#からバッチファイルを起動で
その他(プログラミング・Web制作)
-
5
バッチファイル 二つ上のディレクトリのパス取得
その他(プログラミング・Web制作)
-
6
batからexeを起動した際の戻り値について
その他(プログラミング・Web制作)
-
7
CSVファイルの中で、「 , 」カンマを使いたい
その他(コンピューター・テクノロジー)
-
8
コマンドプロンプトのエラーについて
その他(パソコン・周辺機器)
-
9
C# try-catch でcatchに飛ばす方法
C言語・C++・C#
-
10
日付型のフィールドに空白を入れる方法を教えてください
その他(データベース)
-
11
<a href=#" …>の意味を教えてください。"
HTML・CSS
-
12
コマンドプロンプトのERRORLEVELを取得したい
Visual Basic(VBA)
-
13
System.IO.Directory.GetFilesの順番
Visual Basic(VBA)
-
14
VBA2005 16進を2桁で表示したい。
Visual Basic(VBA)
-
15
exeファイルを実行するとコマンドプロンプトがすぐに閉じる
C言語・C++・C#
-
16
フルパスから最後のディレクトリ名を取得したい。
Visual Basic(VBA)
-
17
Oracleでの文字列連結サイズの上限
Oracle
-
18
【C#/Java?】try-catchでcatchせずにfinallyは一般的?
その他(プログラミング・Web制作)
-
19
実行ファイル(.exe)が別のPCで実行できない
C言語・C++・C#
-
20
OraOps10.dllのエラーについて
Oracle
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
Visual C++からpingを実行して...
-
explorer.exeが異様にメモリを食う
-
ウィンドウのタイトルからプロ...
-
API関数 GetExitCodeProcess
-
プロセスIDからウィンドウハ...
-
WINのタスクマネージャの強制終了
-
タスクマネージャーのプロセス...
-
Linuxでのスレッド間メッセージ...
-
EXE間でデータを受け渡し時のka...
-
C++のプログラムをバックグラウ...
-
完全な乱数を生成する方法
-
WebBrowserでPDF表示でのトラブル
-
VB.NET 自プログラムのプロセス...
-
Windowsでのfork方法
-
ADOでアクセスのレコードに...
-
sleep関数の精度について
-
別のプロセスの関数を呼び出す...
-
VBでエクセルを起動し、プロ...
-
C#でのbatファイル実行結果取得
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
explorer.exeが異様にメモリを食う
-
なぜ女性は男性が忘れたことを...
-
タスクマネージャーのプロセス...
-
プロセスのアタッチ・デタッチ...
-
非表示になったエクセルは?
-
Process.Startの戻り値を後で取得
-
C#でのbatファイル実行結果取得
-
プロセスIDからウィンドウハ...
-
c言語でプロセスIDを調べたい
-
Linuxでのスレッド間メッセージ...
-
プロセスIDの取得方法について
-
ADOでアクセスのレコードに...
-
怪しいプロセス教えてください。
-
vb.netでEXCEL起動がうまくでき...
-
別のプロセスの関数を呼び出す...
-
C++のプログラムをバックグラウ...
-
Visual C++からpingを実行して...
-
VBS(WSH)で開いたIEのウィンド...
-
IISがフリーズ
おすすめ情報