• ベストアンサー

MFCアプリケーションでの終了コードの指定方法

以下の環境でプログラミングを実施しています。 開発環境:Visual Studio 2005 言語:Visual C++ プロジェクト:MFCアプリケーション OS:Windows XP Professional SP2 以下のようにコーディングを行い、任意の終了コードを指定しているつもりですが、 コマンドラインよりプログラム実行後、「echo %errorlevel%」を実行しても 0しか表示されずうまくいきません。 --------------------------------------------------------------------------- // 終了コード用グローバル変数 int g_nRetCode; BOOL CXXXXXApp::InitInstance() { ~~~省略~~~ CWinApp::InitInstance(); ~~~省略~~~ g_nRetCode = Main(); // メイン処理 ~~~省略~~~ return FALSE; } int CXXXXXApp::ExitInstance() { ~~~省略~~~ CWinApp::ExitInstance(); return g_nRetCode; } --------------------------------------------------------------------------- 上記開発環境で任意の終了コードを返すには、どのようにコーディングすれば よいのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

すいません、映画観に行ってました。 結局、原因は(コーディングではなく)、コマンドラインからウィンドウアプリケーションを起動する場合、終了待ちしないということにあります。 start /wait exitCode.exe の様に終了待ちして起動すれば echo %errorlevel% で返値が取れるはず。

mkmarimo
質問者

お礼

ご回答ありがとうございます。 なるほど!終了待ちですか。 確かに実行後まだ処理が継続しているのにコマンドライン上では プロンプトが次の入力を待っていました。 終了待ちをするにはアプリ実行時に上記のように start /wait exitCode.exe とするしかないのでしょうか? Visual C++で処理がすべて終了するまで終了コードを 返さないように簡単にコーディングする方法は ありませんでしょうか? お礼の中での質問になってしまい申し訳ありません。

その他の回答 (3)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.4

MFCで試したことはないのですが... コンソールアプリとしてビルドすれば、期待通りのことができるかもしれません。 具体的には次のようにします。 1. main関数を作成し、main関数からWinMain関数を呼び出す。 2. オプションを修正し、コンソールアプリケーションとしてビルドする。 うまくいけば、コンソールアプリケーションですので、プログラムの終了まで待ってくれるはずです。 また、副次的な効果として、std::coutやstd::cinなどの標準入出力も使えるようになります。

mkmarimo
質問者

お礼

ご回答ありがとうございます。 そんなテクがあったんですね。 けど、プログラム実行後にDOS窓が起動しちゃいませんでしょうか? そうなると少し困ります・・・。 やはり呼び出すときに考慮するようにします。 ありがとうございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

#2>Visual C++で処理がすべて終了するまで終了コードを返さないように簡単にコーディングする方法はありませんでしょうか? 既に述べましたように、コーディングの問題ではなくて、起動する側の問題ですので、コーディングで解決はできません。 起動するプログラムを終了待ちするように起動する必要があります。

mkmarimo
質問者

お礼

たびたびありがとうございます。 呼び出す時に考慮するようにします。 ありがとうございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

終了コードを返すコーディングは、質問者のコードで良いように思います。 ウチでも試してみましたが、この時のコードは、0になっているのではなくてERRORLEVEL にはセットされないようです。 (他のコマンドでERRORLEVELが変更された後、実行しても変化しないので) しかし、 Dim oShell, ret Set oShell = WScript.CreateObject ("WSCript.shell") ret=oShell.run("exitCode.exe",5, true) WScript.Echo ret Set oShell = Nothing のようなVBScript を試してみると、プログラムで設定したリターンコードが表示されるので、ちゃんと終了コード自体は返されているのが確認できます。

関連するQ&A

  • アプリケーションを終了させたい

    Visual C++初心者です。 環境はVisual studio 2005を使用しています。 現在CLRアプリケーションを作っており、押すと終了させるという単純なボタンを作りたいのですが。 検索して調べると、コードに「exit(0);」と書けばいいと書いてあったのでそのようにしてみるとエラーを出しました。(識別子が見つからないとのこと) 終了ボタンをできるだけ簡素なコードで作るにはどうしたらいいでしょうか? よろしくお願いします。

  • 終了コード errorlevel の考え方について

    こんばんは。 OSはWindowsXP Proを使っています。 テキストファイルに書いてある値を 終了コードにするバッチファイルを作成しました。 以下の2ファイルを同じディレクトリに保存します。 test.txt ┌--------┐   1 └--------┘ test.bat ┌---------------------------------------┐   @echo off   find "0" test.txt   if not errorlevel 1 exit /b 0   find "1" test.txt   if not errorlevel 1 exit /b 1   echo テキストは0~1の値ではありません。   exit /b 2 └---------------------------------------┘ この状態で次のように実行します (1) C:\>test.bat ---------- TEST.TXT ---------- TEST.TXT 1 (2) C:\>echo %errorlevel% 1 (3) C:\>set errorlevel=0 (4) C:\>echo %errorlevel% 0 ※ここでtest.txtの中の数字を2にします。 (5) C:\>test.bat ---------- TEST.TXT ---------- TEST.TXT テキストは0~1の値ではありません。 (6) C:\>echo %errorlevel% 0 (7) C:\>set errorlevel= (8) C:\>echo %errorlevel% 2 となります。 (2)の結果から、(1)で実行した「exit /b 1」でerrorlevelに1が格納されることが判ります。 しかし、(6)の結果から、(3)で実行した「set errorlevel=0」が (5)で実行した「exit /b 2」より優先されていることが判ります。 しかし(7)でerrorlevelの値を消去したように思われますが、 (8)の結果から、(3)のセットを消去しつつ(5)で実行した「exit /b 2」を記憶しているように見えます。 この挙動について、どのように理解すれば良いのでしょうか。 また「exit /b ○」と「set errorlevel=○」でセットする違いについて教えて頂ければと思います。 お願いします。

  • デバッグを実行するとC++Builderが強制終了する

    次の開発環境でWindowsアプリを作成しています。  WindowsXP Professional SP2  C++Builder 3 既存のソースに対し、仕様の追加を行う予定です。 ソースの内容を理解すべくデバッグを実施すると、 C++builderが強制終了してしまいます。 以前コーディングしていた方の開発環境では、 強制終了することなくデバッグが行えます。 その方の開発環境を下記します。  WindowsXP Professional  C++Builder 3 この方曰くC++Builder上で設定等は行ってなく デフォルトのままとのこと。 以前コーディングしていた方の環境で行ったように 同じ箇所にブレークポイントを設定するも、私の 環境では強制終了となります。 対象とする行の先頭でクリックし、ブレークポイントを 設定しメニューバー「実行」→「実行」と行ってます。 メニューバー「実行」→「ステップ実行」や メニューバー「実行」→「トレース実行」を 行っても強制終了となります。 ご存じの方すいませんがよろしくお願いします。

  • コンソールアプリケーションの終了方法

    コンソールアプリケーションをC言語(Visual-C++6.0)にて開発予定です。このアプリケーションは画面を使わないのでコンソールアプリケーションにする予定です。このプログラムは常駐プロセスにし、コマンドで起動停止を行うようにする予定です。プログラムの起動はバッチファイルを作成し、そこから実行しようと考えていますが、プログラムを停止させるバッチファイルのイメージがわきません。unixの場合は、当該プロセスにSIGTERMを送信する等の方法が考えられるのですが、windowsで常駐のコンソールアプリケーションを停止させるには、どのような方法があるのでしょうか。ご存じの方ありましたら、教えてください。停止させる方法は、外部から常駐プロセスに停止である旨の何らかの事象を送り、それを常駐プロセスがキャッチし、自ら停止することを想定しています。(有無をいわさず殺すことは考えていません) 実行環境:windows2003を想定 開発言語:VC++6.0でC言語

  • Visual Studio 2008でのC言語のサンプルコード実行につ

    Visual Studio 2008でのC言語のサンプルコード実行について教えてください。 他のプログラミング言語の経験はありますが、C言語とVisual Studioの開発環境は初めてでつまずいています。 C言語で書かれたたくさんのサンプルコードを、 Visual Studioと、Visual Studio コマンドプロンプトでテストしたいのです。 「test」というソリューション(プロジェクト)の下に、「新しいクラス」を追加して、 サンプルコードをコピペして、順次デバックでテストしようとしたところ、 ひとつのプロジェクトの中でmainが重複してしまいエラーになります。 main重複でエラーは当たり前とはいえ、 サンプルコードごとにプロジェクトを作成するのは大げさすぎる気がすることと、 体裁にこだわらず、とにかくデバックで各コードが動くことを確認したいこと、 サンプルコードの書き出し(main関数)などを修正してサブクラスに書き直してデバックすれば mainの重複とみなされず、手軽にVisual Studioでテストできるのではないかと やり方を調べています。 2つ目以降を、サブクラスにすればmainの重複がなくなるでしょうか? その場合、最初のmain関数 int main (int argc, char **argv) をどう修正すればいいのでしょうか。 それとも、何か別のやり方で、Visual Studioで手軽にテストする方法があるでしょうか。 調べてみたのですが、具体策がわからず困っています。 今回初めてVisual Studioに触れましたが、今後長く使いたいので別の環境に逃げずいろいろ勉強したいと思っています。 もし何かお心当たりがありましたら、ぜひ教えてください。 宜しくお願い致します。

  • [MFC]AfxBeginTreadでのスレッド強制終了の方法について

    WinInetで多数のクライアントとHTTP通信を行うプログラムを作成しています。 やりたい事は閉じたネットワークの中で 生きているホストを調べるということです。 HTTP_GETの可否で判断させるつもりですがpingでも構いません。 (DHCPサーバーのリース情報などは参照できない状態環境) 逐次処理で一台ずつタイムアウトは待ってられないので ホストの台数分だけスレッドを作成します(クラスCなら256台分)。 <!-- コード --> UINT MyThreadProc(LPVOID pParam) {  CMyHost* hostData = (CMyHost*)pParam;  hostData->Get();  return 0; } void CMyDlg::OnStart() {  CMyHost hostData[hostNum];  CWinThread* pThread[HostNum];  // 台数分スレッド起動  for (int i=0;i<(int)HostNum;i++) {   hostData[i].ipAddr = NetworkAddress + (DWORD)i;   pThread[i] = ::AfxBeginThread(MyThreadProc, &hostData[i]);  }  // 何秒か待つ  HANDLE timer = CreateWaitableTimer(NULL, FALSE, NULL);  WaitForSingleObject(timer, 10000);  // returnしてないスレッドがあっても全スレッド強制終了  /* 強制終了の仕方が分からない */ <!-- コードここまで --> 強制終了させるためには各スレッドにメッセージを投げて スレッド側でそれを判定するなどでしょうか? でも通信の終わってないスレッドは通信処理の最中なのだから どうやってメッセージを受け取ればいいのか想像つかないです。 (そもそもCInternerSessionでタイムアウトの使い方がよく分からない…、 もっとスマートな方法があれば教えていただきたいです。)

  • MFCダイアログの終了判定

    開発環境:VC++2008 MFCダイアログ プロジェクト作成名:test 簡単なMFCの処理内容を勉強しています。 画像のようなダイアログベースで処理を行っており、 処理の流れは以下です。 1. "参照"で実行ファイルを選択 2. "エディットコントロール"で読み込んだディレクトリの絶対パスを表示 3. "起動"で実行を行う。 上記のプログラムにINIでの保存/読み込みを追加し、(iniは本プログラムと同階層に) 毎回、参照から読み込まなくても、次回以降は自動で変数に読み込まれるようにしようと思ってます。 そこで分からないことが2つあります。  ・質問1: test.cppで閉じるボタンが押されたときに処理を行う方法  ・質問2: INIの同ディレクトリに保存をtestDlg.cpp側で行う方法 質問1補足:  以下のようなOK/キャンセル処理が最初からありますが、  これらのような形式でtest.cpp側で終了判定を行いたいです。 --------------------------------------- INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: ダイアログが <OK> で消された時のコードを // 記述してください。 } else if (nResponse == IDCANCEL) { // TODO: ダイアログが <キャンセル> で消された時のコードを // 記述してください。 } --------------------------------------- ですが、私のプログラムではOK/キャンセルは使っていないので 閉じるボタンを押したとき、上記のような処理をさせることはできないでしょうか? できるならば、そこにINIの保存処理を入れたいと思います。 質問2補足:  test.cppのCtestApp::InitInstance()にて --------------------------------------- TCHAR path[_MAX_PATH+1]; GetModuleFileName( NULL, path, _MAX_PATH ); PathRenameExtension( path, TEXT(".ini") ); free((void*)m_pszProfileName); m_pszProfileName=_tcsdup(path); --------------------------------------- "本プログラムを実行したときと同じディレクトリにINIを保存する" ようにしているので testDlg.cppでボタンを押したときに保存する処理を行うと、 保存される場所がWINDOWSファイルの方に行ってしまうため、 どうしていいかわからない状況です。 初歩的な質問ですが、何卒宜しくお願いします。

  • 関連付け起動と起動時のメッセージ

    VC++6+WinXPにてプログラミングしています CWinAppのInitInstance()にて下記コードを実行しファイルの関連付け起動を行っています。 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); しかし、起動時にはアプリが制御する機械の状態によって、機械の初期化メッセージを表示する必要があるため、同InitInstance()内でAfxMessageBox()によってメッセージを表示させていますが、メッセージが表示される場合は、ファイルが開きません。 メッセージを出すタイミング等についてアドバイスいただけるようでしたら、お願いいたします。

  • アプリケーションの強制終了の原因究明方法(デバッグ)に関して

    問題のアプリケーションはVB6.0で開発されています。動作環境はwinXP SP2です。 自分で開発しているわけではないのですが、社内で使用しているソフトが最近頻繁に 強制終了するので原因を調べたいと思います。しかし、特定の操作でハングアップす るわけではなく、同じ操作をしても普通に動作することもあるし、エラーに再現性が 無くて困っています。 よく強制終了のときに「microsoftに送信しますか」とか出てくる奴なのですが、見て みると問題を起こした関数の入っているファイルの名前や、その命令のあるメモリの アドレスぐらいは出てきます。 しかし具合的に何の命令なのかはわからないし、VC++6.0のデバッガーでアセンブラ で見ても何のことやらさっぱりわかりません。 ネットで検索してWindbgなるものを入れてみたのですが、Minidumpフォルダにダンプ フィルがあるのかと思って探してみても見つからないし、少し行き詰っています。 具体的にエラーストップした命令周辺のコードやそのコードを含むモジュール名など、 もう少し突っ込んだ情報を見られる方法は無いものかと探しています。もちろん、 バッファーオーバーランのように、ストップ箇所=問題箇所とは限らないこともわか っています。 自分でソースコードを持っているわけではないので、コードまでは見られないのかも しれないし、自分で見る必要も無いのかもしれませんが、開発者に状況を伝えるため にもう少し問題箇所の特定につながる情報がほしいと思っています。デバッグの方法 について教えていただけますでしょうか。 よろしくお願いします。

  • C言語ソースコードに関する質問です。

    以下の数列について,初項から第15項までを求めるプログラムと実行結果を示せ。 0 1 1 2 3 5 8 13 21(ただし,初項=0,第1項=1とする。) ソースコードを書くと、エラーがでた。 #include <stdio.h> int fib(int n) { if(n==1 || n==2) return 1; else return fib(n-1)+fib(n-2); } int main(void) { int n; for(n=0;n<17;n++) printf("%d,",fib(n)); } 正しソースコードを教えてください! よろしくお願いします。

専門家に質問してみよう