То, что я намереваюсь сделать, это создать приложение, в котором, помимо прочего, будет встроена встроенная в него командная строка, как это делают некоторые IDE (что-то мне очень полезно).Внедрение CMD-терминала в приложение Winforms C#
Это код, который я до сих пор, не отметить, что это проект Winforms:
public partial class Form1 : Form
{
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;
p.StartInfo = info;
p.Start();
}
private void button1_Click(object sender, EventArgs e) {
using(StreamWriter sw = p.StandardInput) {
if(sw.BaseStream.CanWrite) {
sw.WriteLine(textBox1.Text);
}
}
textBox2.Text = p.StandardOutput.ReadToEnd();
textBox3.Text = p.StandardError.ReadToEnd();
p.WaitForExit();
}
}
}
Как вы можете видеть, что есть 3 текстовые поля и одна кнопка:
- TextBox1 для введя команду
- TextBox2 для стандартного вывода
- textbox3 для STDERR
На моей проблемы:
я могу ввести только один команду, потому что после его выполнения, мое окно CMD исчезает. Я знаю, что он исчезает, потому что я установил info.CreateNoWindow = false;
, и он действительно исчезнет, и если я попытаюсь ввести другую команду, я получаю исключение.
Как бы я продолжал поддерживать мое окно CMD «живым», чтобы я мог использовать его так, как мне нравится? Короче говоря, я хочу по-настоящему имитировать поведение CMD.
Не стесняйтесь спрашивать дополнительную информацию, если что-то неясно.
Extra информация/Что я пробовал:
Я пытался добавить info.Attributes = "/K";
, так как я знаю, что /K
должен держать CMD жив. Я также читал, что p.WaitForExit();
должен сохранять CMD в живых, но из того, что я понял, это только для того, чтобы читать результат. Излишне говорить, что мне это не нужно, поскольку я уже перенаправляю его вывод. Ни одно из этих решений не работает, но вполне возможно, что я использую их неправильно.
мне нужно этот процесс живой, чтобы я мог легко перемещаться с помощью cd
и выполнения последовательности команд, когда это необходимо, например, при доступе к ftp
или mysql
. Я знаю, что могу обойти эти два примера с параметрами, но не для каждого приложения. Короче говоря, нереста нового процесса каждый раз не то, что я хочу. Я хочу, чтобы интерфейс CMD постоянно работал.
ЦМД процесс умирает после того, как
using(StreamWriter sw = p.StandardInput) {
if(sw.BaseStream.CanWrite) {
sw.WriteLine(textBox1.Text);
}
}
Но я не могу точно определить, почему.
Это выражение 'using' вызывает' p.StandardInput' для удаления ('sw' - это просто ссылка на него). Не делайте этого - удаляйте 'p' вместо (когда вам это больше не нужно). –
@PieterWitvoet Спасибо за ваш ответ. Таким образом, в основном p удаляется, когда я оставляю область использования? Как я буду продолжать использовать StreamWriter без инструкции 'using'? Я попытался объявить StreamWriter в методе 'Form1_Load' и впоследствии получить доступ к выходному' p.StandardOutput', но мое приложение зависает без каких-либо исключений. Не могли бы вы уточнить, пожалуйста? – xIcarus
Независимо от того, что вы используете, используется в конце блока 'using', поэтому каждый раз, когда вы вводите команду, ваш код удаляет стандартный ввод вашего процесса. Вы по существу распоряжаетесь частью объекта и ожидаете, что он продолжит работу, как раньше. Просто удалите этот оператор 'using'. 'sw' - это не новый писатель потока, за который вы отвечаете - это ссылка на' p.StandardInput'. Устранение 'p' позаботится об утилизации этих потоковых писателей для вас. –