Bu yolla bir kabuklara komut gönderemezsiniz. Info.Arguments içindeki dize, komut satırındaki programa sağlanan argümanlardır. Cmd.exe kabuğunun bir komut dizisini yürütmesini ve ardından çıkmasını istiyorsanız,/c argümanını sağlamanız gerekir. Eğer gerçekleştirmek istediğiniz birden çok komutunuz varsa, ya komutları bir toplu iş dosyasına yerleştirmeli ve bunları yürütmeli ya da bunları tırnak içine almalı ve bunları & &, yani info.Arguments = @"/c ""cd \ && dir""";
ile ayırmalısınız. Asla geri dönmeyecek olan diğer sorununuz, cmd.exe'nin herhangi bir ya da uygun argüman olmadan çalıştırıldığında varsayılan olarak etkileşimli modda açılmasından kaynaklanır./C seçeneği cmd.exe'ye ilgili komutları yürütmesini ve sonra çıkmasını söyler. Ayrıca, Python ve perl gibi çevirmenlerin, bazen doğrudan ProcessStartInfo'dan başlatıldığında garip davranışları vardır. info.Arguments = @"""MyPerlProgram.pl""";
with perl.exe çalışmıyorsa, onları, örn. info.Arguments = @"/c ""perl.exe ""MyPerlProgram.pl""""";
yerine normal davranış göstermek için cmd.exe dosyasının içinde başlatmak gerekir.
Bkz. Cmd ve ProcessStartInfo.Arguments Property.
Sorununuzu yanıtlamak için, 3 numaralı sorunu bildirin, muhtemelen çıkışlara yanlış takılmamış olabilirsiniz. StreamReader'ın BaseStream'i kancalamaya çalışmak yerine, ProcessOutputHandler'ın public static void ProcessOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
gibi bir imzası olduğu Start'ı çağırmadan önce OutputDataReceived olayını this.shellProcess.OutputDataReceived += ProcessOutputHandler;
ile kancalayın. Başlat'ı aradıktan hemen sonra, this.shellProcess.BeginOutputReadLine();
'u arayın. İşlem, hata çıkışında da benzerdir. Daha fazla ayrıntı için bkz. Process.BeginOutputReadLine Method ve Process.BeginErrorReadLine Method.
Eğer hala bir probleminiz varsa, process.StartInfo.Arguments = @"/c ""python.exe -c ""import sys; print 'Test.';""""";
'u denerseniz, ne elde edersiniz?
Ayrıca, kod aşağıda kabuk iletişim için gerekli kavramların çoğu gösterir: Eğer sorunlara neden parçacığı sorunları olabilir
public static void Main()
{
using (Process process = new Process())
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.WorkingDirectory = @"C:\";
process.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe");
// Redirects the standard input so that commands can be sent to the shell.
process.StartInfo.RedirectStandardInput = true;
// Runs the specified command and exits the shell immediately.
//process.StartInfo.Arguments = @"/c ""dir""";
process.OutputDataReceived += ProcessOutputDataHandler;
process.ErrorDataReceived += ProcessErrorDataHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// Send a directory command and an exit command to the shell
process.StandardInput.WriteLine("dir");
process.StandardInput.WriteLine("exit");
process.WaitForExit();
}
}
public static void ProcessOutputDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
Console.WriteLine(outLine.Data);
}
public static void ProcessErrorDataHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
Console.WriteLine(outLine.Data);
}
. Bununla bazı başka çalışma yaptık ve aşağıdaki kodla güncellemek için bir form üzerinde bir metin kutusu elde edebilir ettik:
: Ben bir form oluşturulur ve bir metin kutusu ve form aşağıdaki kodu eklendi
using System;
using System.Diagnostics;
using System.IO;
using System.Timers;
namespace DummyFormsApplication
{
class ProcessLauncher : IDisposable
{
private Form1 form;
private Process process;
private bool running;
public bool InteractiveMode
{
get;
private set;
}
public ProcessLauncher(Form1 form)
{
this.form = form;
process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.WorkingDirectory = @"C:\";
process.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe");
// Redirects the standard input so that commands can be sent to the shell.
process.StartInfo.RedirectStandardInput = true;
process.OutputDataReceived +=new DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived += new DataReceivedEventHandler(process_ErrorDataReceived);
process.Exited += new EventHandler(process_Exited);
}
public void Start()
{
if (running == false)
{
running = true;
InteractiveMode = true;
// Runs the specified command and exits the shell immediately upon completion.
process.StartInfo.Arguments = @"/c ""C:\python27\python.exe -i""";
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
}
public void Start(string scriptFileName)
{
if (running == false)
{
running = true;
InteractiveMode = false;
// Runs the specified command and exits the shell immediately upon completion.
process.StartInfo.Arguments = string.Format(@"/c ""C:\python27\python.exe ""{0}""""", scriptFileName);
}
}
public void Abort()
{
process.Kill();
}
public void SendInput(string input)
{
process.StandardInput.Write(input);
process.StandardInput.Flush();
}
private void process_OutputDataReceived(object sendingProcess, DataReceivedEventArgs outLine)
{
if (outLine.Data != null)
{
form.Invoke(form.appendConsoleTextDelegate, new object[] { outLine.Data });
}
}
private void process_ErrorDataReceived(object sendingProcess, DataReceivedEventArgs outLine)
{
if (outLine.Data != null)
{
form.Invoke(form.appendConsoleTextDelegate, new object[] { outLine.Data });
}
}
private void process_Exited(object sender, EventArgs e)
{
running = false;
}
public void Dispose()
{
if (process != null)
{
process.Dispose();
}
}
}
}
public delegate void AppendConsoleText(string text);
public AppendConsoleText appendConsoleTextDelegate;
private void Form1_Load(object sender, EventArgs e)
{
appendConsoleTextDelegate = new AppendConsoleText(textBox1_AppendConsoleText);
using (ProcessLauncher launcher = new ProcessLauncher(this))
{
launcher.Start();
launcher.SendInput("import sys;\n");
launcher.SendInput("print \"Test.\";\n");
launcher.SendInput("exit()\n");
}
}
private void textBox1_AppendConsoleText(string text)
{
textBox1.AppendText(string.Format("{0}\r\n", text));
}
Unutulmaması gereken bir şey, eğer Form1_Load olayı tamamlanmazsa, Invoke bunu yapana kadar askıda kalacaktır. Bir etkinlikte uzun süredir devam eden bir kodunuz varsa, BeginInvoke kullanarak senkronize olmayan bir şekilde çağırmanız veya uzun süren kodunuzda periyodik olarak DoEvent'leri çağırmanız gerekir.
DÜZENLEME Yorumlarınız Başına
, ben interaktif gönderimleri ile çalışmak için kod modifiye ettik. Bununla birlikte, bir sorun var. Python istemi (>>>
) StandardError çıktısında sağlanmıştır ve StandardInput'u yansıtmaz. Ayrıca hattı sonlandırmaz. Bu, işlemin sonlanmasının zorlaşmasını ve işlem bitene veya satır sonu görünene kadar process_ErrorDataReceived'e bağlı olarak komut istemcisinin bazı sipariş çıkışlarının çıkmasına neden olur.
Merhaba Jamie, Lütfen yardımcı olabilecek bir örnek veya bağlantı sunabilir misiniz, lütfen? – Gagan
Bir örnek info.Arguments cmd.exe için cevabın üstesinden gelinmiş ve sürecin neden kendi başına bitmediğine dair açıklama ekledi. – JamieSee
Güncelleme 3 ile ilgili çözümle ilgili yanıt güncellendi. – JamieSee