В приложении WinForm, которое вызывает сторонний инструмент командной строки, может быть время, когда инструмент ожидает ввода данных пользователем, например, спрашивает, следует ли перезаписать файл:
printf("%s already exists, overwrite?: <Y>es, <N>o, <A>ll, <Q>uit?",FName);
for ( ; ; )
switch ( toupper(getch()) ) {
case 'A':
YesToAll=true;
case '\r':
case 'Y':
remove(FName);
return true;
case 0x1B:
case 'Q':
printf("quit\n"); exit(-1);
case 'N':
return false;
}
Когдав таком случае я хочу отобразить сообщение от printf()
и параметры в диалоговом окне и перенаправить нажатие кнопки в качестве входных данных для процесса.Вероятно, для отправки ввода используется System.Diagnostics.Process.StandardInput
.Но не зная, когда именно инструмент будет ожидать ввода, я бы не знал, когда реагировать соответствующим образом в графическом интерфейсе.Когда процесс находится в этом цикле for, мой процесс WinForm просто остановится.
РЕДАКТИРОВАНИЕ : вот код, который разблокирует пользовательский интерфейс, запустив процесс в другом потоке, однако я все еще не смог прочитать вывод, если выбранный файл вызовет перезапись инструмента.опции.proc_OutputDataReceived
( EDIT2 : или readStdOut
в случае proc.StandardOutput.BaseStream.BeginRead
) никогда не будет вызываться, если инструмент не запрашивает ввод).
private BackgroundWorker worker = new BackgroundWorker();
private void fileChosenHandler(object sender, EventArgs e)
{
OpenFileDialog dialog = sender as OpenFileDialog;
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerAsync(dialog.FileName);
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
string exePath = @"F:\test\test.exe";
Process proc = new Process();
proc.StartInfo.FileName = exePath;
proc.StartInfo.Arguments = "\"" + (string)e.Argument + "\"";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
proc.Start();
// method 1: read lines
//proc.BeginOutputReadLine();
// method 2: read characters
proc.StandardOutput.BaseStream.BeginRead(stdOutBuffer, 0, stdOutBuffer.Length, readStdOut, proc);
proc.WaitForExit();
}
private void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
MessageBox.Show("Output: " + e.Data);
}
private byte[] stdOutBuffer = new byte[20];
private void readStdOut(IAsyncResult result)
{
Process proc = result.AsyncState as Process;
int bytesNumber = proc.StandardOutput.BaseStream.EndRead(result);
if (bytesNumber != 0)
{
string text = System.Text.Encoding.ASCII.GetString(stdOutBuffer, 0, bytesNumber);
MessageBox.Show("Output: " + text);
}
// set up the callback again
proc.StandardOutput.BaseStream.BeginRead(stdOutBuffer, 0, stdOutBuffer.Length, readStdOut, proc);
}
Любая идеякак это сделать?Спасибо!