16

Process processWindows 用の基本的なシェルを作成していますが、現在のコンソール ウィンドウを使用するようにサブプロセス ( ) を実行する方法があるかどうか疑問に思っていました。これは、入出力をリダイレクトしたくないという意味です。プロセスが現在のコンソールから入力を取得し、出力を同じコンソール ウィンドウに直接出力する必要があります。

その理由は、このサブプロセスが出力用にコンソールの色を設定できるようにしたいからです。これは、プロセスの標準出力をリダイレクトすると発生しません。また、私は現在コードを使用しています

while (!process.HasExited)
    process.StandardInput.WriteLine(Console.ReadLine());

標準入力をプロセスにリダイレクトします。ただし、入力の直後にプロセスが終了した場合 (たとえば、「exit」+ ENTER を入力してプロセスが終了した場合)、このループがもう一度実行されるため、コンソールは使用されないユーザーからの入力を待機しています。プロセスによって (終了しようとしています)。

では、短い質問ですが、現在のコンソールでプロセスを実行して、コンソールの色を設定し、コンソールから直接入力を取得するにはどうすればよいですか?

編集:以下は、私のコードからのこの質問に関連するメソッドです:

static int runExe(string exePath, params string[] args)
{
    ProcessStartInfo startInfo = new ProcessStartInfo(exePath, args)
    {
        ErrorDialog = false,
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        RedirectStandardInput = true
    };
    Process process = new Process() { StartInfo = startInfo };
    process.Start();
    ReadThreadState stdout = readThread(process.StandardOutput, false);
    ReadThreadState stderr = readThread(process.StandardError, true);
    while (!process.HasExited)
        process.StandardInput.WriteLine(Console.ReadLine());
    stdout.stop = stderr.stop = true;
    return process.ExitCode;
}
class ReadThreadState
{
    public bool stop;
}
private static ReadThreadState readThread(StreamReader reader, bool isError)
{
    ReadThreadState state = new ReadThreadState();
    new Thread(() =>
    {
        while (!state.stop)
        {
            int current;
            while ((current = reader.Read()) >= 0)
                if (isError)
                    writeError(((char)current).ToString(), ConsoleColor.Red);
                else
                    Console.Write((char)current);
        }
    }).Start();
    return state;
}
4

2 に答える 2

2

ジム・ミシェルの答えは魅力的です。いくつかのバッチ ファイル処理を C# に移行していますが、うまくいきます。この小さなユーティリティ メソッドが便利な場合があります。コマンド ラインを取得して、バッチ ファイルの CALL と同じように実行します。ユーティリティクラスに詰め込むだけです:

public static void RunCmd(string command) {
    Process.Start(new ProcessStartInfo("cmd.exe", "/c " + command) {
        UseShellExecute = false
    }).WaitForExit();            
}    
于 2014-03-19T23:20:25.503 に答える