私は、Mercurialコマンドラインクライアントと話すクラスライブラリを変更しようとしています。1.9クライアントの新機能は、サーバをスピンアップして標準の入出力パイプを介してそれを話す能力です。これは本当に有望です。Mercurialコマンドラインクライアントを使用する際の重大な頭痛の1つは、Pythonで書かれているので、バージョンを尋ねるだけでも、クライアントをスピンアップするオーバーヘッドが少しあります。入力ストリームを連続的にフラッシュするために.NET Processオブジェクトを取得しますか?
しかし、1つの問題があります。今までは、標準出力/エラーを読み込んでコマンドラインクライアントから出力を取得しました。プロセスが終了すると、ストリームがフラッシュされ、ストリームの終わりを読み取ることができます。
しかし、この新しいモードでは、プロセスは多くのテキストを標準エラー出力にダンプし、次のコマンドを待っています。オーバーヘッドを減らすのに最適ですが、.NETがそれらのストリームをバッファリングするので、厄介です。私は別のコマンド に発行
- :プロセスが終了しないので、言い換えれば は、私がするまでその出力の最後の部分を得ることはありません
- に私のための方法は、私がバッファ内にあるものは何でも得ることを意味し、フラッシュするEVをバッファを掲載ありバッファをそれ自身でフラッシュするのに十分でない場合は?
- もしそうでなければ、バッファサイズを1文字に設定できますか?
- 他に何かできますか?
私はP/Invokeを処理することができます。
は、ここで説明しますLINQPad概念実証プログラムです:それは何
は、コマンドプロンプトをスピンアップし、それをDIRコマンドを送り、しかしそれらの10秒は、ループ内で経過していないまでということに気づくですプログラムはディレクトリ一覧を作成した直後にコマンドプロンプトが出力する "C:>"プロンプトを出力しますか?
つまりが、これはコマンドプロンプトが何をするかです:
- 促すことにより
- は、別のコマンドを求める上場プロデュースディレクトリ:
はしかし、これは "C> \"以下のプログラムは見るもの:
- プロデュースディレクトリリスト を210
- (10秒待つ)
- 入力ストリーム
を閉じますが、プロンプト
無効メイン(){ 文字列clientExecutablePath =「CMDを参照してください。exeファイル ";
var psi = new ProcessStartInfo(); psi.FileName = clientExecutablePath; psi.RedirectStandardError = true; psi.RedirectStandardInput = true; psi.RedirectStandardOutput = true; psi.CreateNoWindow = true; psi.WorkingDirectory = @"C:\"; psi.WindowStyle = ProcessWindowStyle.Hidden; psi.UseShellExecute = false; psi.ErrorDialog = false; psi.StandardErrorEncoding = Encoding.GetEncoding("Windows-1252"); psi.StandardOutputEncoding = Encoding.GetEncoding("Windows-1252"); var p = Process.Start(psi); var input = p.StandardInput; var output = p.StandardOutput; var error = p.StandardError; Action<StreamReader, string> reader = delegate(StreamReader streamReader, string prefix) { string line; while ((line = streamReader.ReadLine()) != null) { Debug.WriteLine(prefix + line); } }; IAsyncResult outputReader = reader.BeginInvoke(output, "o: ", null, null); IAsyncResult errorReader = reader.BeginInvoke(error, "e: ", null, null); input.Write("dir\n"); input.Flush(); while (!p.HasExited) { Thread.Sleep(10000); input.Close(); } reader.EndInvoke(outputReader); reader.EndInvoke(errorReader);
}
私は今、それが説明する正規CMD.EXEプログラムを使用して、Mercurialの依存をドロップするようにプログラムを変更しました。 –
こんにちは、私はここで同じ問題を抱えています。そしてもしそうなら、どうですか? :) – FrieK