0

この次のコードでは、dir などのコマンドを送信するたびに、この関数が while ループに陥ります。コマンドの実行後にプロセスを閉じずに実行するコマンドを送信するたびに、コマンドプロンプトの出力が必要です。

public void shell(String cmd)
{
        ProcessStartInfo PSI = new ProcessStartInfo();
        PSI.FileName = "c:\\windows\\system32\\cmd.exe";
        PSI.RedirectStandardInput = true;
        PSI.RedirectStandardOutput = true;
        PSI.RedirectStandardError = true;
        PSI.UseShellExecute = false;
        Process p = Process.Start(PSI);
        StreamWriter CSW = p.StandardInput;
        StreamReader CSR = p.StandardOutput;
        CSW.WriteLine(cmd);
        CSW.Flush();
        while(!(CSR.EndOfStream))
        {
            Console.WriteLine(CSR.ReadLine());
        }

        CSR.Close();

}

以下は完全なコードです:-

 namespace ConsoleApplication8
 {

     class Program
     {
         public static void shell(String cmd)
         {

             ProcessStartInfo PSI = new ProcessStartInfo();
             PSI.FileName = "c:\\windows\\system32\\cmd.exe";
             PSI.RedirectStandardInput = true;
             PSI.RedirectStandardOutput = true;
             PSI.RedirectStandardError = true;
             PSI.UseShellExecute = false;
             Process p = Process.Start(PSI);
             StreamWriter CSW = p.StandardInput;
             StreamReader CSR = p.StandardOutput;
             CSW.WriteLine(cmd);
             CSW.Flush();
             while (!(CSR.EndOfStream))
             {
                 Console.WriteLine(CSR.ReadLine());
             }

             CSR.Close();

         }
         static void Main(string[] args)
         {
             string cmd="";
             while (cmd != "exit")
             {
            cmd=Console.ReadLine();
            shell(cmd);
             }
         }
     }
 }

目的 --> コマンド プロンプトのコマンドを実行するためのユーザー アクセスを与えるプログラムを作成したい。上記のプログラムは、コマンドを送信するたびに cmd.exe プロセスを作成します。しかし、それは大きな問題ではありません。簡単に修正できます..主な問題は、コマンドを送信するたびに、プログラムが while (!(CSR.EndOfStream)) でスタックすることです

4

2 に答える 2

1

このコードで試すことができます

         ProcessStartInfo PSI = new ProcessStartInfo();
         PSI.FileName = "c:\\windows\\system32\\cmd.exe";
         //PSI.RedirectStandardInput = true;
         PSI.RedirectStandardOutput = true;
         PSI.RedirectStandardError = true;
         PSI.UseShellExecute = false;
         Process p = Process.Start(PSI);
         StreamWriter CSW = p.StandardInput;

         string output = p.StandardOutput.ReadToEnd(); 

         Console.WriteLine(output);
于 2012-10-10T04:15:55.670 に答える
0

入力ストリームに直接書き込むときに cmd.exe がハングするという問題を再現できました。このようにプログラムを実行すると、.NET は出力ストリームがいつ終了したかを認識できないため、ReadToEnd() を呼び出すと (またはストリームの終わりまでしばらく時間がかかる場合)、無期限にハングします。あなたの最善の策は、引数として提供されたコマンドで cmd.exe を開始するこのようなことをすることです。次に、コマンドの実行が終了したら、出力ストリームを閉じる必要があることを認識し、制御を呼び出し元に戻します。

ここに例があります。

static void Main()
{
    while (true)
    {
        Console.Write("> ");
        string input = Console.ReadLine();
        string output = RunCommand(input);
        Console.WriteLine(output);
    }
}

static string RunCommand(string command)
{
    Process p = Process.Start(new ProcessStartInfo()  {
        FileName = "cmd",
        Arguments = "/c \"" + command + "\"",
        RedirectStandardError = true,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        UseShellExecute = false
    });

    string output = p.StandardOutput.ReadToEnd();
    string error = p.StandardError.ReadToEnd();
    p.WaitForExit();
    return output + error;
}

これが生成する出力の例を次に示します。

> echo hello, world
hello, world

> ping google.com

Pinging google.com [74.125.225.199] with 32 bytes of data:
Reply from 74.125.225.199: bytes=32 time=63ms TTL=49
Reply from 74.125.225.199: bytes=32 time=61ms TTL=49
Reply from 74.125.225.199: bytes=32 time=61ms TTL=49
Reply from 74.125.225.199: bytes=32 time=61ms TTL=49

Ping statistics for 74.125.225.199:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 61ms, Maximum = 63ms, Average = 61ms

>
于 2012-10-10T04:15:08.533 に答える