Z;\>hoge.exe > log.txt
このようにすると、標準出力がファイルにリダイレクトできます。
ところが微妙に複雑な仕様があるらしく、若干うまくいかなかったのでメモ。
状況
普通に実行すると、標準出力にテキストを色々吐くプログラムがあり…
Z;\>hoge.exe I love beef! I love pork!ファイルにリダイレクトすると、出力されないものがある。どういうこっちゃ。
Z;\>hoge.exe > log.txt Z;\>type log.txt I love beef!
解明
テスト用のソースコードは以下。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <tchar.h> | |
#include <Windows.h> | |
#include <wincon.h> | |
int _tmain(int argc, _TCHAR* argv[]) | |
{ | |
TCHAR *lbuf = L"I love beef!\n"; | |
CHAR *buf = "I love pork!\n"; | |
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); | |
CONSOLE_SCREEN_BUFFER_INFO scrInfo; | |
DWORD wroteSize; | |
GetConsoleScreenBufferInfo(hStdout, &scrInfo) | |
? printf("GetConsoleScreenBufferInfo: OK\n") | |
: printf("GetConsoleScreenBufferInfo: NG\n"); | |
SetConsoleTextAttribute(hStdout, BACKGROUND_RED | FOREGROUND_BLUE) | |
? printf("SetConsoleTextAttribute: OK\n") | |
: printf("SetConsoleTextAttribute: NG\n"); | |
WriteConsole(hStdout, lbuf, lstrlen(lbuf), &wroteSize, nullptr) | |
? printf("WriteConsole: OK\n") | |
: printf("WriteConsole: NG\n"); | |
SetConsoleTextAttribute(hStdout, scrInfo.wAttributes); | |
WriteFile(hStdout, buf, strlen(buf), &wroteSize, nullptr) | |
? printf("WriteFile: OK\n") | |
: printf("WriteFile: NG\n"); | |
return 0; | |
} |
リダイレクトしなかった場合の出力: (実際には微妙な色で装飾される)
GetConsoleScreenBufferInfo: OK SetConsoleTextAttribute: OK I love beef! WriteConsole: OK I love pork! WriteFile: OK
リダイレクトした場合にファイルに書かれる内容:
I love pork! GetConsoleScreenBufferInfo: NG SetConsoleTextAttribute: NG WriteConsole: NG WriteFile: OK
- ファイルにリダイレクトされた場合、Console関係の関数は失敗する
- WriteConsole
- GetConsoleScreenBufferInfo
- SetConsoleTextAttribute
- WriteFileはリダイレクトの有無にかかわらず成功する
- (w)printfはリダイレクトの有無にかかわらず成功する
そういう挙動が嫌なら、WriteConsoleは使わずにWriteFileを使うのがよさそうです。着色のために呼ぶConsole関係の関数が失敗しても、気にせずWriteFile。