状況は次のとおりです。ソケットを介して要求を処理し、実行中のマシンにUIを公開していない構築サーバーがあります。受信した要求に基づいて、ビルドスクリプト(通常はMSバッチファイル)を起動し、生成されたファイルを提供します。診断目的のために、stdoutとstderrをパイプにリダイレクトしてビルドスクリプトを起動し、この出力をビルドサーバーアプリケーションによってバッファに保存し、ビルドを要求したクライアントに渡します。ビルドが失敗した場合は、ビルドを要求した人がエラーメッセージの内容を確認できます。コンソール以外のプロセスによるコンソール出力のリダイレクト
デバッグ時に、このビルドサーバーはコンソールアプリケーションとしてビルドされました。診断メッセージ(クライアントの接続、要求の作成など)。すべてが正常に機能したら、コンソール以外のアプリとして再構築しました。
突然、アプリケーションの動作が変更されました。パイプによって捕捉された出力は、バッチファイルによって直接生成された出力(すなわち、エコーはオフではないので、エコーされたコマンド)にのみ減少した。バッチファイル(MSBuild、nmakeなど)によって起動されたサブプロセスは、コンソールウィンドウを開き、その出力をパイプではなくウィンドウに指示しました。
私は、アプリケーションがコンソールアプリケーションであったとき、コンソールアプリケーションが自身の入出力を管理しようとせず、実行中のコンソールから継承し、I/O上の_dup2
生きている。したがって、すべてうまくいった。しかし、親ビルドサーバーがコンソールウィンドウを作成しない状況では、バッチファイルによって生成されたサブプロセスは、独自のI/Oを作成し、ビルドサーバーを取得した出力を奪取する必要がありました。サーバーのデスクトップに接続されている人には非常に迷惑をかけています)。
基本的に質問は簡単です:どのようにコンソール以外のアプリケーションを起動し、この動作を防ぐことができますか?私はEmacsのシェルモードはWindows以外のコンソールアプリケーションのキャプチャとリダイレクトコマンド出力の例であるため、ほとんどのコンソールアプリケーションでは原則的に可能であることはわかっていますが、どうやってそれを行うのか分かりません。
現在、私は、Win32のPOSIX風味のCRT関数を使用しています:_pipe
、_dup
、_dup2
、_close
、_spawnvp
、および_read
を。私はこれらが "本物の" win32関数の周りに薄いラッパーであることを知っていますが、私は自分でCreateProcess
と友人に渡って苦労しないように訓練することによってUNIXの男です。
ビルドサーバは実際にはHaskellで書かれており、リンクCはより簡単なので、開発言語はCでなければなりません。 (あなたのハスケラーの皆さんのために、私は自分自身のスポーン/リダイレクトコードを巻いて、System.Processを使わずにFFIにリンクしました。stdout
とstderr
の両方がリダイレクトされている必要があり、Windowsではこれは些細なことです純粋なハスケル)。
もちろん、私はコンソールアプリケーションとしてビルドサーバーを使用して、サーバー上でそれを最小限に抑えるだけで大したことではありません。しかし、私はむしろ...どんなアイデアでもないでしょうか?
EDIT:私はstdinで何もしないことを言及するかもしれません。私はstdin fdを作成するべきでしょうか?これらのスクリプトは対話型ではありません。
リンク先のようなリダイレクトの問題に一般的に対処するいくつかの質問があります。それは私の問題ではありません。 *親プロセスがコンソールアプリケーションでもあると仮定して、子コンソールプロセスの出力をリダイレクトすることができます*特に、そのスレッドで提案されている解決策はすべて、基本的に '_pipe'と '_dup2'です。 – 808140
私はあなたの質問を誤って読んだようです。私はあなたがCreateProcessに乗り込むことなくあなたが望むことをすることができるとは思わない。これは、子プロセスのstd *ハンドルをプログラムで制御できる唯一の方法です。 –