0

クライアントがサーバーに接続し、そのサーバーで MS DOS コマンドを実行できるようにする単純なプログラムを C# で作成しています。

プログラムはうまく機能しました。後で、クライアントがサーバーに接続されている間に cmd.exe プロセスを実行することにしました。ここで行き詰まっています。CDなどのコマンドを実行して作業ディレクトリを変更できるようにするために、これが必要でした。以前は、コマンドの実行後に cmd.exe プロセスが閉じられたため、これは効果がありませんでした。

StandardOutputプロセスが終了した場合にのみStandardErrorストリームから読み取ることができるようです。これに対する回避策はありますか?

プログラムで使用されているコードの一部を次に示します。

* cmd.exe プロセスを作成して返します: *

private Process createDOS()
{
    try
    {
        // Create a ProcessStartInfo class
        ProcessStartInfo startInfo = new ProcessStartInfo("cmd","");

        // Set up the values
        startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
        startInfo.UseShellExecute = false;
        startInfo.RedirectStandardOutput = true;
        startInfo.RedirectStandardError = true;
        startInfo.RedirectStandardInput = true;
        startInfo.CreateNoWindow = false;

        // Create a cmd.exe process
        Process process = new Process();

        // Apply the start info and run
        process.StartInfo = startInfo;

        process.Start();  

        return process;
    }
    catch (Exception)
    {
        return null;
    }
}

レスポンスを文字列にフォーマットするメソッド:

private string findResponse(StreamReader err,StreamReader outp)
{
    string output = outp.ReadToEnd();
    string error = err.ReadToEnd();

    string ret = "";

    // Add the output to the return field if the process actually output data
    if (output.Length > 0)
    {
        ret = "OUTPUT : " + output;
    }

    // Then attempt to add data from the error stream
    if (error.Length > 0)
    {
        // If output was read, add a newline character separating the two fields
        if (ret.Length > 0) ret = ret + Environment.NewLine;
        ret = ret + "ERROR : " + error;
    }

    // If there's no output, that means there's no error, which means the execution was silently succesful
    if (ret.Length <= 0)
    {
        ret = "Command execution succesful!";
    }
    return ret;
}

サーバーリスナーブロック:

private void run()
{
    while (true)
    {

        Stream stream = null;
        StreamReader sr = null;
        StreamWriter sw = null;
        Socket socket = null;
        Process proc = null;

        try
        {
            socket = server.AcceptSocket();

            stream = new NetworkStream(socket);

            sr = new StreamReader(stream);
            sw = new StreamWriter(stream);

            String mode = sr.ReadLine();

            sw.WriteLine("Serverside link connected");
            sw.Flush();

            // Create cmd process in WINPROCESS mode

            if (mode == "WINPROCESS")
            {
                proc = createDOS();
            }

            String line;
            while ((line = sr.ReadLine()) != null)
            {
                if (mode == "WINPROCESS")
                {
                    proc.StandardInput.WriteLine(line);
                    proc.StandardInput.Flush();

                    // Response
                    sw.WriteLine(findResponse(proc.StandardError, proc.StandardOutput));
                    sw.Flush();

                }
                else
                {
                    sw.WriteLine(exeDOS(line));
                    sw.Flush();
                }
            }

        }
        catch (Exception ex)
        {
            // Silence
        }
        finally
        {
            if (socket != null) socket.Close();
            if (stream != null) stream.Close();
            if (sw != null) sw.Close();
            if (sr != null) sr.Close();
            if (proc != null) proc.Close();
        }
    }
}

どんな助けでも大歓迎です、ありがとう!

4

1 に答える 1

0

OutputDataReceivedおよびErrorDataReceivedイベントにハンドラーを追加する必要があります。

    process.StartInfo.RedirectStandardOutput = true;
    process.OutputDataReceived += 
        new DataReceivedEventHandler(process_OutputDataReceived);

    process.StartInfo.RedirectStandardError = true;
    process.ErrorDataReceived += 
        new DataReceivedEventHandler(process_ErrorDataReceived);

    if (process.Start())
    {
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
        process.WaitForExit();
    }
}

void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine(e.Data);
}

void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine(e.Data);
}
于 2013-02-26T13:55:52.567 に答える