Вопрос по c#, .net – C # Windows Form .Net и DOS Console

4

У меня есть форма Windows, которая выполняет командный файл. Я хочу перенести все, что происходит в моей консоли, на панель в моей форме. Как я могу это сделать? Как моя консоль DOS может взаимодействовать с панелью Windows?

Спасибо

Ваш Ответ

6   ответов
1

в котором я взаимодействовал с пакетными файлами. Я нашел этот фрагмент кода, который позволил мне сделать это:

Process proc = new Process
               {
                   StartInfo =
                       {
                           RedirectStandardError = true,
                           RedirectStandardOutput = true,
                           UseShellExecute = false,
                       }
               };
proc.Start();

string errorMessage = proc.StandardError.ReadToEnd();
proc.WaitForExit();
string outputMessage = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();

Отсюда, просто направьте эти строки в пользовательский контроль по вашему выбору.

редактирует

Note: This is not a general solution. It can lead to deadlocks. From the doc for RedirectStandardError:
Synchronous read operations introduce a dependency between the caller reading from the StandardError stream and the child process writing to that stream. These dependencies can cause deadlock conditions. When the caller reads from the redirected stream of a child process, it is dependent on the child. The caller waits for the read operation until the child writes to the stream or closes the stream. When the child process writes enough data to fill its redirected stream, it is dependent on the parent. The child process waits for the next write operation until the parent reads from the full stream or closes the stream. The deadlock condition results when the caller and child process wait for each other to complete an operation, and neither can continue. You can avoid deadlocks by evaluating dependencies between the caller and child process.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0

что есть лучшие варианты, но вы можете перенаправить вывод команды во временный файл

Перенаправление вывода командной строки в файлы

For programs that display a lot of text, consider redirecting text that is usually displayed on stdout to a file. Displaying a lot of text will slow down execution; scrolling text in a terminal window on a workstation can cause an I/O bottleneck (increased elapsed time) and use more CPU time.

The following commands show how to run the program more efficiently by redirecting output to a file and then displaying the program output:

myprog > results.lis more results.lis Redirecting output from the program will change the times reported because of reduced screen I/O.

Я думаю, что вы также можете просто направить его к переменной, но не на 100% уверены. Возможно, есть гораздо лучшие варианты, но по крайней мере это один из вариантов.

7

направить вывод в строку:

using (var p = new System.Diagnostics.Process( ))
{
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.FileName = PathToBatchFile;
    p.StartInfo.Arguments = args;
    p.Start( );
    string o = p.StandardOutput.ReadToEnd( );
    p.WaitForExit( );
}
Error: User Rate Limit Exceeded user62958
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

Док утверждает что если вы хотите прочитать и StandardError и StandardOutput, вам нужно прочитатьat least one of them асинхронно, чтобы избежать тупиков.

Кроме того, если вы вызываете ReadToEnd в одном из перенаправленных потоков, вы должны сделать этоbefore вызывая WaitForExit (). Если вы подождите WaitExExit перед ReadToEnd, выходной буфер может заполниться, приостановив процесс, что означает, что он никогда не завершится. Это было бы очень долго ждать. Это тоже в док!

пример:

string output;
string error;
System.Diagnostics.Process p = new System.Diagnostics.Process
    {
        StartInfo =
        {
            FileName = program,
            Arguments = args,
            WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
            UseShellExecute = false,
        }
    };

if (waitForExit)
{
    StringBuilder sb = new StringBuilder();
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.RedirectStandardError = true;
    Action<Object,DataReceivedEventArgs> stdErrorRead = (o,e) =>
    {
        if (!String.IsNullOrEmpty(e.Data))
            sb.Append(e.Data);
    };

    p.ErrorDataReceived += stdErrorRead;
    p.Start();
    // begin reading stderr asynchronously
    p.BeginErrorReadLine();
    // read stdout synchronously
    output = p.StandardOutput.ReadToEnd();
    p.WaitForExit();
    // return code is in p.ExitCode

    if (sb.Length > 0)
        error= sb.ToString();

}
1

приложений, а также для форматирования и возврата выходных данных. Я думаю, что это будет работать и с пакетными файлами. Я возьму момент, чтобы проверить это. Вот пример кода:

   System.Diagnostics.ProcessStartInfo start = new System.Diagnostics.ProcessStartInfo();
    start.UseShellExecute = false;
    start.RedirectStandardInput = true;
    start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;

    start.RedirectStandardOutput = true;
    start.FileName = "at";
System.Diagnostics.Process myP = System.Diagnostics.Process.Start(start);
String strOutput = myP.StandardOutput.ReadToEnd();
if (strOutput.Contains("There are no entries in the list."))
{
    litMsg.Text = "There are no jobs";
}
else
{
    strOutput = strOutput.Replace("\r", "");
    foreach (String line in strOutput.Split("\n".ToCharArray()))
    {
        //(0,7)  (7,5)(12, 24)                (36, 14)      (50, )
        //Status ID   Day                     Time          Command Line
        //-------------------------------------------------------------------------------
        //        1   Tomorrow                3:00 AM       dir *
        if (line.Length > 50)
        {
            String Status = line.Substring(0, 7);
            String ID = line.Substring(7, 5);
            String Day = line.Substring(12, 24);
            String Time = line.Substring(35, 14);
            String Command = line.Substring(49);
        }
    }
}
2

System.Diagnosticsзатем вызывая командный файл следующим образом:

string myFile = "c:\\path\\to\\batch_file.bat";
ProcessStartInfo psi = new ProcessStartInfo(myFile);
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
Process proc = Process.Start(psi);

Теперь, если вы хотите, чтобы вызов блокировался (т. Е. Ваше приложение зависло до завершения файла), просто используйтеstring result = proc.StandardOutput.ReadToEnd() прочитать весь вывод вашего пакетного файла.

Однако если вы хотите, чтобы приложение продолжало отвечать, а также отображало выходные данные в режиме реального времени, вам необходимо будет использоватьBeginOutputReadLine.

Похожие вопросы