Win32GUIアプリを作成しています。そのアプリ内では、コマンドラインアプリで使用することを目的としたDLLを使用しています。
Foo.exeが私のGUIアプリであり、bar()が「hello」をstdoutに出力するDLLの関数であるとします。Foo.exeはbar()を呼び出します。
コマンドラインからリダイレクト(>)(つまり)を使用してFoo.exeを実行すると、Foo.exe > out.txt
out.txtに「hello」が書き込まれ、正常に終了します(予想どおり)。
ただし、リダイレクトせずに(cmd.exeから、またはWindowsエクスプローラーでダブルクリックして)Foo.exeを実行すると、bar()が呼び出されたときにクラッシュします。
コマンドラインでリダイレクト(プロジェクトのVSのプロパティを介して設定)を使用してデバッガー内でFoo.exeを実行し、「GetStdHandle(STD_OUTPUT_HANDLE)」を呼び出すと、ハンドルの適切なアドレスを取得します。コマンドラインでリダイレクトせずに呼び出すと、0になります。
標準を「初期化」するために何かが必要ですか?アプリケーションの起動時にこのリダイレクトを設定する方法はありますか?(ファイルにリダイレクトするのが理想的ですが、DLLによって出力されたデータを破棄するだけでも問題ありません。)
最後に、クロスプラットフォームDLLであるため、DLLがCRTPOSIXのようなAPIを介してstdoutに書き込んでいるのではないかと思います。これが重要かどうかはわかりません。
CreateFileを使用してファイルを作成し、SetStdHandleを呼び出してみましたが、うまくいかないようです。ただし、ファイルを間違って作成している可能性があります。以下のコードを参照してください。
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
// hStdOut is zero
HANDLE hFile;
hFile = CreateFile(TEXT("something.txt"), // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_NEW, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
BOOL r = SetStdHandle(STD_OUTPUT_HANDLE, hFile) ;
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
// hStdOut is now equal to hFile, and r is 1
bar();
// crashes if there isn't a redirect in the program arguments
更新:この記事を見つけました:http ://support.microsoft.com/kb/105305 。「このコードはハンドル0、1、2の問題を修正しないことに注意してください。実際、他の問題のため、これを修正することはできません。したがって、lowではなくstream I/Oを使用する必要があります。 -レベルI/O。」
私のDLLは間違いなくファイルハンドル0、1、2を使用しています。したがって、この問題に対する適切な解決策がない可能性があります。
このケースをチェックし、CreateProcessを使用してexeを適切に再起動するソリューションに取り組んでいます。終わったらここに投稿します。