2012-02-20 3 views
2

У меня есть процесс, который вызывает исполняемый файл fortran. Исполняемый файл запрашивает файл у пользователя и выполняет операции по поиску решения. Если в файле обнаружено несколько решений, программа спросит пользователя, хотят ли они найти наиболее оптимальное решение, в основном 2 входа для программы. Затем исполняемый файл генерирует текстовый файл, который предоставляет результаты программы.C# Процесс, не принимающий входы

Процесс может работать, однако полученный текстовый файл не генерируется. Кроме того, когда я проверял вывод приложения, приглашение сообщения («Ввести файл») является единственной вещью, хранящейся в строке, и она не включает вторичное приглашение для оптимального решения («Хотели бы вы найти наиболее оптимальное решение? »). Может ли кто-нибудь дать мне представление о том, почему это происходит? Благодарю.

Process exeProcess = new Process(); 
exeProcess.StartInfo.FileName = "sdf45.exe"; 
exeProcess.StartInfo.UseShellExecute = false; 
exeProcess.StartInfo.RedirectStandardError = true; 
exeProcess.StartInfo.RedirectStandardInput = true; 
exeProcess.StartInfo.RedirectStandardOutput = true; 
exeProcess.Start();   
//input file     
exeProcess.StandardInput.WriteLine(Path.GetFileName(filePath));    
//find optimal solution 
exeProcess.StandardInput.WriteLine("Y"); 
string output = exeProcess.StandardOutput.ReadToEnd();    
exeProcess.WaitForExit(); 
+0

Как исполняемый файл запрашивает файл у пользователя? – Tigran

+0

Итак, я вижу, что вы перенаправляете стандартную ошибку, не читая ее. Это может вызвать проблемы, если программа много пишет для стандартной ошибки. – Servy

+0

Исполняемый файл запрашивает имя файла, который находится в том же каталоге, что и исполняемый файл. – BeingIan

ответ

0

Это трудно сказать, но я полагаю, что вам нужно передать аргументы к исполняемому файлу, как этот

Process exeProcess = new Process(); 
exeProcess.StartInfo.FileName = "sdf45.exe"; 
exeProcess.StartInfo.UseShellExecute = false; 
exeProcess.StartInfo.RedirectStandardError = true; 
exeProcess.StartInfo.RedirectStandardInput = true; 
exeProcess.StartInfo.RedirectStandardOutput = true; 
exeProcess.StartInfo.Arguments = Path.GetFileName(filePath); //pass file path to EXE 
exeProcess.Start(); 

Надеется, что это помогает

+1

От OP, кажется, что имя файла передается через stdin (после подсказки), а не параметры. –

+0

@ChrisShain: не очень чистый фактически * это * пункт. Было бы хорошо, если бы Оп пояснил это. – Tigran

1

Я думаю, что эта линия выполняет (и возвращается) до того, как процесс FORTRAN даже имеет возможность прочитать ввод:

string output = exeProcess.StandardOutput.ReadToEnd(); 

Я не уверен на 100%, что результат ReadToEnd(); в неограниченном потоке в этом случае. Правильный способ сделать это, как уже упоминалось, Джон тарелочкам here, чтобы читать стандартный вывод в другом потоке или еще лучше асинхронно, как описано здесь: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline.aspx

Ради потомства грубый пример:

var outputReader = new Thread(ReadOutput); 
outputReader.Start(exeProcess); 

где ReadOutput определяется что-то вроде этого:

public void ReadOutput(Object processState) { 
    var process = processState as Process; 
    if (process == null) return; 
    var output = exeProcess.StandardOutput.ReadToEnd(); 
    // Do whetever with output 
} 

Создание вашего первоначального метода:

Process exeProcess = new Process(); 
exeProcess.StartInfo.FileName = "sdf45.exe"; 
exeProcess.StartInfo.UseShellExecute = false; 
exeProcess.StartInfo.RedirectStandardError = true; 
exeProcess.StartInfo.RedirectStandardInput = true; 
exeProcess.StartInfo.RedirectStandardOutput = true; 
exeProcess.Start();   
//input file     
exeProcess.StandardInput.WriteLine(Path.GetFileName(filePath));    
//find optimal solution 
exeProcess.StandardInput.WriteLine("Y"); 
var outputReader = new Thread(ReadOutput); 
outputReader.Start(exeProcess); 
exeProcess.WaitForExit(); 
outputReader.Join(); 
+0

Несмотря на то, что чтение из стандарта - это совсем не плохая идея, я считаю маловероятным, что это проблема OPs.ReadToEnd блокируется, поэтому он не возвращается до тех пор, пока программа не отправит сообщение о конце потока, которое программа не отправит, пока не будет готова к завершению (если какой-то средний/некомпетентный программист не записывает маркер EOS в стандартную версию, когда еще есть больше контента для записи). – Servy

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