- ベストアンサー
標準出力をDOS窓を開かずにファイルに書き込む方法
- VC++のConsole Appliで、標準出力結果をファイルに吐き出す方法を教えてください。
- DOS窓を表示せずに、標準出力結果をファイルに書き込む方法を教えてください。
- VC++で標準出力をファイルに保存する方法について、DOS窓の表示をせずに実現する方法を教えてください。
- みんなの回答 (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; }
その他の回答 (4)
- sakusaker7
- ベストアンサー率62% (800/1280)
乗りかかった船、ということでやってみました。 短くするためところとことん切り詰めましたが、それでも 1600バイトをようやく切るぐらいになったしまったので次の発言に プログラムを貼り付けます。 一応、Windows 2000上で正常動作することは確認しています。 使うときにはエラーチェックをしっかりやってください。
お礼
えっ!、と思わず驚いています。 わざわざ、ありがとうございました。 今日は半日、これで潰れてしまい、諦めかけていました。 動作確認してみます。 本当にありがとうございました。
- sakusaker7
- ベストアンサー率62% (800/1280)
連続して発言してすみません。 よく読み返したら、コンソールアプリから呼び出しって書いてありますね。 であれば、 #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; } で、新しいコンソールは出てきませんでしたけど?
補足
すみませんでした。 コンソールアプリというのが嘘で、実際は、 cmdDlg.cppファイルで //cmdDlg ダイアログ //cmdDlg メッセージ ハンドラ などの処理も入っています。 CreateProcessを駆使して・・・、かなり以前にもこちらで教えて頂きながらチャレンジしたのですが、どうにも自分の理解能力を超えていて、いま、少しあきらめかけています。 一縷の望みは、 CreateProcess() の引数 STARTUPINFO 構造体にある hStdOutput に何か出力されるように思っています。 これをファイルに受けられればと思っています。
- sakusaker7
- ベストアンサー率62% (800/1280)
↓こんなので試してみましたが、コマンドの出力は受け取れたものの コンソールが表示されてしまいました。 どうも 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; }
補足
ありがとうございます。 ご提示のソース内容のようなことを私もやってみました。 その際に、 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)
コマンドの出力を受け取りたいということなら、popen (_popen)を使ってみてはどうでしょう? 多分コンソールも出てこないと思います。
補足
ご回答ありがとうございました。 popen()というようなi/fがあったのですね。従来からなんでもsystem()でファイルリダイレクトさせて対応していました・・・ それで、_popenを試してみたのですが、どうしてもNULLしか返してきません。 ヘルプを見ると、 『メモ _popen 関数を Windows プログラムで使用すると、無効なファイルハンドルを返し、プログラムがハングアップする原因となります。』 に関連しているようにも思います。 creating_a_child_process_with_redirected_input_and_output に関して、調べてみたいと思います。
お礼
長い間が開いてしまい、すみませんでした。 ご丁寧なご回答ありがとうございました。
補足
お礼が遅くなりすみませんでした。 結局、まだ検証が中途半端なままなのですが、 一応DOS窓が消して実行できる状態にはなっています。 また何かあれば具体的症状を沿えて別upするようにします。