2009-06-24 3 views
4

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

Благодаря

ответ

7

Вы можете позвонить в DOS или пакетную программу из вашей формы приложения и перенаправить вывод в строку:

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(); 
} 
+0

Вы, вероятно, хотите, чтобы переместить вызов WaitForExit() перед строкой, которая считывает входные данные из перенаправлены выходного потока. Кроме того, при желании вы можете добавить флаг WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden, чтобы консольное приложение не появлялось, если оно не требует взаимодействия с пользователем. – LBushkin

+0

Спасибо ... И есть способ, которым я могу скрыть окно ОС ??? Он работает прямо сейчас, но показывает пустые консоли ОС ... – user62958

+1

Перед чтением ввода вам не нужно WaitForExit, но вам нужно выполнить Dispose() после этого. Я добавил это. Неизвестный Yahoo, я не вижу консольного окна, вы уверены, что это пакетный файл? Попробуйте установить p.StartInfo.CreateNoWindow = true; –

1

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

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); 
     } 
    } 
} 
1

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

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(); 

здесь, просто направить эти строки в UserControl вашего выбора.


редактирует

Примечание: Это не является общим решением. Это может привести к взаимоблокировкам. Из документа для RedirectStandardError:
Операции синхронного чтения вводят зависимость между показанием вызывающего абонента из потока StandardError и записью дочернего процесса в этот поток. Эти зависимости могут привести к условиям взаимоблокировки. Когда вызывающий абонент читает из перенаправленного потока дочернего процесса, он зависит от дочернего элемента. Вызывающий абонент ждет операции чтения до тех пор, пока ребенок не будет записываться в поток или не закрывает поток. Когда дочерний процесс записывает достаточно данных для заполнения перенаправленного потока, он зависит от родителя. Детский процесс ждет следующей операции записи, пока родитель не прочитает полный поток или не закрывает поток. Условие взаимоблокировки возникает, когда вызывающий и дочерний процессы ждут друг друга для завершения операции, и они не могут продолжаться. Вы можете избежать взаимоблокировок, оценивая зависимости между вызывающим и дочерним процессами.

+1

На самом деле это не сработает, потому что между stderr и stdout существует состояние гонки. Предположим, что процесс, который вы запускаете, записывает сначала в stdout, затем в stderr. Вызывая ReadToEnd() на stderr, вы будете ждать всегда. С другой стороны, если процесс записывается в обратном порядке, то чтение из stderr в порядке. Но нет никакой гарантии. Следовательно, состояние гонки. Вы должны использовать асинхронные чтения, чтобы избежать этой гонки. Дополнительную информацию смотрите в документе Process.Start(). – Cheeso

+0

Полагаю, именно поэтому этот код привел к тому, что время от времени зависало в моем пакетном окне. Я чувствовал, что что-то может быть из-за удара. Я собираюсь оставить свой ответ неверным в образовательных целях. –

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); 

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

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

0

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

Redirecting Command-Line Output to Files

Для программ, которые отображают много текста, рассмотрите перенаправлять текст что обычно отображается на стандартном диске в файле . Отображение большого количества текста будет замедлить выполнение; прокручивание текста в терминальное окно на рабочей станции может вызвать узкое место ввода-вывода (увеличено истекшее время) и использовать больше времени процессора.

Следующие команды показывают, как эффективно работать программа больше, перенаправлять вывод в файл, а затем отображение вывода программы:

MyProg> results.lis больше results.lis Перенаправление выход из программы изменит время сообщения, потому что сокращенного ввода-вывода.

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

3

The doc states, что если вы хотите прочитать как StandardError и StandardOutput, вам нужно прочитать по крайней мере один из них асинхронно, чтобы избежать тупиков.

Кроме того, если вы вызываете ReadToEnd в одном из перенаправленных потоков, вы должны сделать это до, вызвав WaitForExit(). Если вы WaitForExit перед 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(); 

} 
Смежные вопросы