標準出力をDOS窓を開かずにファイルに書き込む方法

このQ&Aのポイント
  • VC++のConsole Appliで、標準出力結果をファイルに吐き出す方法を教えてください。
  • DOS窓を表示せずに、標準出力結果をファイルに書き込む方法を教えてください。
  • VC++で標準出力をファイルに保存する方法について、DOS窓の表示をせずに実現する方法を教えてください。
回答を見る
  • ベストアンサー

標準出力をDOS窓を開かずにファイルに書き込む方法

VC++(Console Appli)です。 あるコマンドの標準出力結果をファイルに吐き出す方法として、 単純には、 system("cmnd > C:\\temp.txt"); とやれば実現できますが、このとき、一瞬ですが、DOS窓の黒枠が表示されます。 このDOS窓を出さないで済む方法があれば教えてください。 標準出力を何らかの方法で受け取って、 ------------------------------------------------- CString str; CStdioFile file;   :  cmndの標準出力結果をstrへ内部的に受け取らせる。   : file.Open(_T("c:\\temp.txt"), CFile::modeWrite); file.WriteString(str); file.Close(); ------------------------------------------------- などで簡単に出来れば良いのですが・・よろしくお願いします。

  • goku3
  • お礼率78% (97/123)

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

#include <windows.h> #include <stdio.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { SECURITY_ATTRIBUTES pa, ta; BOOL bInheritHandles = TRUE; DWORD dwCreationFlags; LPVOID lpEnv = NULL; LPCSTR lpCurDir = NULL; STARTUPINFO info; PROCESS_INFORMATION pi; HANDLE hStdIn, hStdOut; char buff[1024]; DWORD readsize; FILE *fp; dwCreationFlags = CREATE_NEW_CONSOLE; ZeroMemory(&pi, sizeof pi); ZeroMemory(&pa, sizeof pa); pa.nLength = sizeof pa; pa.lpSecurityDescriptor = NULL; pa.bInheritHandle = TRUE; ZeroMemory(&ta, sizeof ta); ta.nLength = sizeof ta; ta.lpSecurityDescriptor = NULL; ta.bInheritHandle = TRUE; if (!CreatePipe(&hStdIn, &hStdOut, &pa, 0)) return 2; ZeroMemory(&info, sizeof info); info.cb = sizeof info; info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW ; info.hStdOutput = hStdOut; info.hStdError = hStdOut; info.hStdInput = INVALID_HANDLE_VALUE; info.wShowWindow = SW_HIDE; if(!CreateProcess(NULL, "ls -l", &pa, &ta, TRUE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &info, &pi)) return 3; WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(hStdOut); fp = fopen("o.txt", "w"); if (!fp) return 4; while (ReadFile(hStdIn, buff, sizeof buff, &readsize, NULL)) fwrite(buff, readsize, 1, fp); return 0; }

goku3
質問者

お礼

長い間が開いてしまい、すみませんでした。 ご丁寧なご回答ありがとうございました。

goku3
質問者

補足

お礼が遅くなりすみませんでした。 結局、まだ検証が中途半端なままなのですが、 一応DOS窓が消して実行できる状態にはなっています。 また何かあれば具体的症状を沿えて別upするようにします。

その他の回答 (4)

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

乗りかかった船、ということでやってみました。 短くするためところとことん切り詰めましたが、それでも 1600バイトをようやく切るぐらいになったしまったので次の発言に プログラムを貼り付けます。 一応、Windows 2000上で正常動作することは確認しています。 使うときにはエラーチェックをしっかりやってください。

参考URL:
http://search.acty-net.ne.jp/mfc_search/archive/2001-2/msg02079.html,http://support.microsoft.com/kb/q190351/
goku3
質問者

お礼

えっ!、と思わず驚いています。 わざわざ、ありがとうございました。 今日は半日、これで潰れてしまい、諦めかけていました。 動作確認してみます。 本当にありがとうございました。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.3

連続して発言してすみません。 よく読み返したら、コンソールアプリから呼び出しって書いてありますね。 であれば、 #include <stdio.h> #include <stdlib.h> #include <process.h> int main() {   const char* cmd = "ls";   FILE *fp;   char buf[1024];   fp = _popen(cmd, "r");   if (!fp) {     fprintf(stderr, "can't execute %s\n", cmd);     exit(1);   }   while (fgets(buf, sizeof buf, fp))     printf("get: %s\n", buf);   close(fp);   return 0; } で、新しいコンソールは出てきませんでしたけど?

goku3
質問者

補足

すみませんでした。 コンソールアプリというのが嘘で、実際は、 cmdDlg.cppファイルで //cmdDlg ダイアログ //cmdDlg メッセージ ハンドラ などの処理も入っています。 CreateProcessを駆使して・・・、かなり以前にもこちらで教えて頂きながらチャレンジしたのですが、どうにも自分の理解能力を超えていて、いま、少しあきらめかけています。 一縷の望みは、 CreateProcess() の引数 STARTUPINFO 構造体にある hStdOutput に何か出力されるように思っています。 これをファイルに受けられればと思っています。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

↓こんなので試してみましたが、コマンドの出力は受け取れたものの コンソールが表示されてしまいました。 どうも WindowsAPI の CreateProcessを駆使して処理する必要があるようです。 #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <process.h> //#define CMD "cmd.exe /c dir /od" #define CMD "ls.exe -l" int WINAPI WinMain(   HINSTANCE hInstance,   HINSTANCE hPrevInstance,   LPSTR lpCmdLine,   int nCmdShow ) {   const char* cmd = CMD;   FILE *ifp;   FILE *ofp;   char buf[1024];   ifp = _popen(cmd, "r");   if (!fp) {     MessageBox(NULL, "Can't execute process", "Info", MB_OK);     exit(1);   }   ofp = fopen("output.txt", "w");   if (!ofp) {     MessageBox(NULL, "Can't open output file", "Info", MB_OK);     exit(1);   }      while (fgets(buf, sizeof buf, ifp))     fputs(buf, ofp);   close(fp);   close(ofp);   MessageBox(NULL, "Done", "Infomation", MB_OK);      return 0; }

goku3
質問者

補足

ありがとうございます。 ご提示のソース内容のようなことを私もやってみました。 その際に、  ifp = _popen(cmd, "r");  if (!fp) {     MessageBox(NULL, "Can't execute process", "Info", MB_OK);     exit(1);  } ここで、fp==NULLの動作になってしまいます。 ※【重要】 あと、 私自身、質問の初っ端で、VC++(Console Appli)と自ら書いていながら、 実際には、実行すると簡単なダイアログウィンドウを表示し、 内部的にも、OnOK()やら、OnCancel()などの制御をしていました。 余計なお手間もお掛けし、申し訳ありませんでした。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

コマンドの出力を受け取りたいということなら、popen (_popen)を使ってみてはどうでしょう? 多分コンソールも出てこないと思います。

goku3
質問者

補足

ご回答ありがとうございました。 popen()というようなi/fがあったのですね。従来からなんでもsystem()でファイルリダイレクトさせて対応していました・・・ それで、_popenを試してみたのですが、どうしてもNULLしか返してきません。 ヘルプを見ると、 『メモ _popen 関数を Windows プログラムで使用すると、無効なファイルハンドルを返し、プログラムがハングアップする原因となります。』 に関連しているようにも思います。 creating_a_child_process_with_redirected_input_and_output に関して、調べてみたいと思います。

関連するQ&A

  • プラスが文字化け

    開発環境 ・Windows XP (32bit) ・Visual C++ 2005 ・マルチバイト文字セット CStdioFileクラスを使用してのファイル出力で、 以下のような処理を実行したところ文字化けしてしまいました。 文字化けを回避するにはどうすれば良いでしょうか? アドバイスお願いします。 CStdioFile file(_T("C:\\XXX\\YYY.txt"), CFile::modeCreate | CFile::modeWrite); // "+"の後ろが数値となる文字列 CString str(_T("0.000e+000")); file.Write(str, str.GetLength()); ↑の実行結果をエディタで開くと"0.000eMモ"となってしまいます。

  • DOS窓で・・・

    Win95または98のDOS窓で コマンドの標準出力と標準エラー出力を テキストファイルにリダイレクトしたいのですが どのようにすればよいのでしょう? できれば標準の機能でサポートされていると良いのですが フリーソフトとかでできるのをご存知であれば ご教授頂ければ幸いです。

  • DOSからLPT1への出力をファイルに出力できますか

    DOS窓において LPT1ポートにプリント出力しています。 このプリントを用紙に出力せず、ファイルに出力できますか。

  • Visual StudioでDOS窓以外に出力する方法は?

    Visual Studio 2008 を使って、プログラミングの勉強をしてます。 まだコンソールアプリだけで、フォームアプリの勉強には入って いません。 ですので、出力は Console.WriteLine を使ってますけど、これで プログラムを実行すると、DOS窓に出力されます。結果を見るだけなら それでもいいんですけど、DOS窓からはクリップボードにコピーが 出来ないので、たとえば出力結果をこの掲示板に載せて質問したい 時とかは、自分でそれを見ながら打ち込まなければなりません。 DOS窓を開いて exe ファイルを叩いて実行すれば、ファイルに リダイレクト出来るのは分るんですけど、ディレクトリを移動する だけでも面倒ですし、プロジェクトごとにディレクトリが変わるので PATH を切っておく方法も使えません。Visual Studio から実行した 出力結果を、ファイルに出す方法ってありますでしょうか? 今はプロジェクトを作る時に「空のプロジェクト」を選んで、 「コードファイル」を追加してソースコードを打ち込んでます。

  • 画像の保存方法。

    VC++のMFC、ダイアログベースで画像処理のソフトを開発している者です。 ピクチャーコントロールに画像を表示させて、その画像を保存したいと思っています。 保存用のダイアログを開き、名前を付けて保存したいのですがうまくいきません。 下が今作っているプログラムです。 void Cstart2Dlg::OnBnClickedButton10() { CFileDialog myDLG(FALSE,"BMP","*.BMP", OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "画像(*.BMP)|*.BMP||"); if(myDLG.DoModal() == IDOK){ CStdioFile fout(myDLG.GetPathName(),CFile::modeCreate |CFile::modeWrite|CFile::typeBinary); UpdateData(TRUE); fout.WriteString(m_pict8); fout.WriteString("\xla"); filename = myDLG.GetPathName(); SetWindowText("start2"+filename); } ピクチャーコントロールの変数をm_pict8にしています。テキストファイルを保存するプログラムを参考にして作っているので間違っているのだと思います。 画像の保存方法が分かる方がいらっしゃいましたらよろしくお願いいたします。

  • perl 出力について

    Win98SEのDOS窓で、たとえば perl -w a.cgi というふうにするとエラーなどがDOS窓に出力されると思いますが、それがたくさんあるとスクロールして上のほうが見れないんですがどうすれば見れるのでしょうか? >a.txt などと付け加えると処理結果(?)はファイルに出力されるのですが、エラーのメッセージなどはファイルに出力されません、DOS窓に表示されたままです。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • 標準出力/標準エラー出力を時系列にファイルへ

    画面への文字出力が、標準出力(stdout)と標準エラー出力(stderr)の 両方もつような、コンソールアプリ(exe形式)のツールを動作させたときに、 画面上には、 stdout1 STDERR1 stdout2 STDERR2 stdout3 STDERR3 のような順番で処理順にメッセージが出るのですが、 これをファイルに落とそうとして、  C:\>hoge.exe 1> log.txt 2>1& とすると、log.txtの中身が、 C:\>type log.txt STDERR1 STDERR2 STDERR3 stdout1 stdout2 stdout3 のような標準エラー出力が先に吐き出される順番になってしまっています。 これを、exe実行前に、MS-DOSとして何らかの設定を行うことで、 ファイルに落とした時も、出力された文字が時系列に保存されるように する方法はあるでしょうか? よろしくお願いします。

  • Win98DOS窓でのファイルネームについて

    Windows98のDOS窓を使用する際での疑問なんですが、 ファイルネームは (1)Windowsの長い形式 (2)DOS用の短い形式 があると思いますが、DOS窓において(1)から(2)を知るには どういった方法があるのでしょうか?

  • 標準出力しながらファイルに出力

    標準出力に表示したものを、そのままファイルに書き込むことは可能でしょうか? 例えば下記のように実現できるかと思いますが、printする度に2行書くのは厳しく思ってます。 ----------------------------- open(OUT, "> outfile.txt") ; print $aaa ; print OUT $aaa ; -----------------------------

  • DOS窓の非表示

    環境:Windows2000,BorlandC++Builder6 system()関数によりDOS上で動く実行ファイルの呼び出し をしています。その際,DOS窓が一瞬出ます。 どうにかDOS窓が出ないようにしたいのですが, 何か方法はないでしょうか? どなたか分かりましたら教えて下さいm(__)m

専門家に質問してみよう