Я создал кнопку, которая запускает процесс «CMD» и пингует конкретную машину.
Я успешно выполнил Ping и изменил текст кнопки вперед и назад после нажатия кнопки, но я не уверен, как ОСТАНОВИТЬ процесс ping (который является командой ping -t) при втором щелчке того же кнопка.
ЗДЕСЬ мой код на данный момент, который выбирает кнопку, изменяет текст при нажатии, запускает процесс и проверяет наличие ошибок. Я попытался добавить оператор «else» и сказать proc.Kill(), но он не может найти переменную proc везде, где я пытаюсь. Есть ли правильный способ сделать это?
public void Btn_Ping_Click_1(object sender, EventArgs e)
{
if (Btn_Ping.Text == "Ping")
{
Btn_Ping.Text = "Stop Ping";
}
else if (Btn_Ping.Text == "Stop Ping")
{
Btn_Ping.Text = "Ping";
}
th = new Thread(thread1);
th.Start();
}
public void thread1()
{
if (Btn_Ping.Text == "Stop Ping")
{
try
{
string command = "/c ping " + Txt_Main.Text.Trim() + " -t";
ProcessStartInfo procStartInfo = new ProcessStartInfo("CMD", command);
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutPutDataRecieved);
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
catch (Exception)
{
//If an error occurs within the try block, it will be handled here
}
}
void proc_OutPutDataRecieved(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
string newLine = e.Data.Trim() + Environment.NewLine;
MethodInvoker append = () => richTextBox1.Text += newLine;
richTextBox1.BeginInvoke(append);
}
}
}
Вторя тому, что я сказал ниже, я не могу поверить, что не подумал сделать это. Спасибо. Здесь новый разработчик, и я часто скучаю по таким мелочам :(
Объявить proc на уровне класса (а не внутри thread1). Затем добавьте к кнопке событие Click:
if (proc != null)
{
if (!proc.HasExited)
proc.Kill();
proc = null;
}
else
{
th = new Thread(thread1);
th.Start();
}
Ничего себе, я не могу поверить, что я не подумал просто объявить proc в классе. Угу, спасибо.
Я попытался сказать Process proc = new Process(); выше в классе, а также просто сказать Process proc; и инициировать его ниже, но ни один из них не работает. Первоначальный пинг просто продолжается.
Используйте объекты Task, а не потоки. Передайте им объекты CancelationToken следующим образом:
private CancellationTokenSource _cts = null;
public void Btn_Ping_Click_1(object sender, EventArgs e)
{
if (Btn_Ping.Text == "Ping")
{
_cts = new CancellationTokenSource();
Btn_Ping.Text = "Stop Ping";
var task = new Task(() => task1(cts.Token));
task.Start();
}
else if (Btn_Ping.Text == "Stop Ping")
{
Btn_Ping.Text = "Ping";
_cts.Cancel();
}
}
public void task1(CancellationToken ct)
{
try
{
string command = "/c ping " + Txt_Main.Text.Trim() + " -t";
var procStartInfo = new ProcessStartInfo("CMD", command);
var proc = new Process {StartInfo = procStartInfo};
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutPutDataRecieved);
proc.Start();
proc.BeginOutputReadLine();
while (!proc.WaitForExit(250))
{
if (ct.IsCancellationRequested)
{
proc.Kill();
return;
}
}
}
catch (Exception)
{
//If an error occurs within the try block, it will be handled here
}
}
Разве вы не можете просто объявить Process в классе и вызвать Kill в другом методе?