2015-05-25 5 views
3

Я пытаюсь убить процесс по идентификатору процесса, который я сохраняю при запуске процесса. Но идентификатор процесса, который я собираю, не существует, когда я пытаюсь убить процесс из кода позади.Идентификатор процесса процесса Начал с начала процесса

Это код ниже, чтобы начать процесс и получить идентификатор процесса.

private List<int> pids = new List<int>(); 
public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      pids.Clear(); 
      Process myprocess= new Process(); 

      myprocess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\cmdkey.exe"); 
      myprocess.StartInfo.Arguments = "C:\\rdp\\RemoteIn.rdp"; 
      myprocess.Start(); 
      pids.Add(myprocess.Id);   
     } 

     private void terminateAll() 
     { 
      //foreach (var p in pids) p.Kill(); 

      foreach (var i in pids) 
      { 
       Process p = Process.GetProcessById(i); 
       p.Kill(); 

      } 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      terminateAll(); 
     } 

Когда я нажимаю кнопку, чтобы завершить процесс, отображается следующая ошибка.

enter image description here

Есть ли способ, чтобы исправить это.

После использования кода Palani Kumar, я становлюсь ниже исключения. enter image description here

форма Похоже, этот

enter image description here

+1

Попробуйте сохранить объект Process в своем списке, а не только идентификатор. – Blorgbeard

+0

Да, вместо хранения pids просто сохраните сам процесс, тогда вам даже не нужно вызывать 'Process.GetProcessById (i); ' – spender

+1

возможный дубликат [получения PID процесса, запущенного Process.start()] (http://stackoverflow.com/questions/12892268/getting-pid-of-process-started-by-process- start) –

ответ

1

Я не знаю, почему вы объявили ИДП как List<int> и очистил список (pids.Clear();) на события нажатия кнопки. В любом случае ниже будет работать и для создания нескольких процессов.

EDIT: Как обсуждалось ранее с Amrit. Windows 8 создание подпроцессов для mstsc с подключением одного домена. Поэтому я немного изменил свой код.

private void button1_Click(object sender, EventArgs e) 
    { 
     //pids.Clear(); 
     Process myprocess = new Process(); 

     myprocess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\syswow64\mstsc.exe"); 
     myprocess.StartInfo.Arguments = "C:\\rdp\\RemoteIn.rdp"; 
     myprocess.Start(); 
     Thread.Sleep(100); 
     /* Edit */ 
     Process proc = Process.GetProcessesByName("mstsc").FirstOrDefault(x => !pids.Any(y => y == x.Id)); 
     if(proc != null) 
     { 
      pids.Add(proc.Id); 
     } 
    } 

И

private void terminateAll() 
    { 
     foreach (var i in pids) 
     { 
      try 
      { 
       Process p = Process.GetProcessById(i); 
       p.Kill(); 
      } 
      catch (Exception ex) 
      { 
       //throw exception if we close the mstsc manually 
      } 
     } 
    } 
+0

Он работает как шарм, если я просто открываю один файл .rdp. Но когда я открываю другой файл .rdp, он выдает над ошибкой. –

+0

Вы прокомментировали эту строку "pids.Clear();" –

+0

Да, я прокомментировал pids.Clear() –

0

Я не уверен, почему вы держите

private List<int> pids = new List<int>(); 

вместо использования только список Process непосредственно

private List<Process> processes = new List<Process>(); 

Это важно понимать, что процесс объект имеет дескриптор безопасности. Каждый может видеть существование процесса, кто-то может открыть процесс для чтения информации или для ожидания завершения процесса. Для убийства требуется больше прав. Обработчик процесса, возвращаемый CreateProcess, имеет полные разрешения. Поэтому наличие объекта Process, используемого для создания процесса, дает вам такие преимущества.

Я бы порекомендовал вам дополнительно проверить HasExited объект Process объект перед вызовом Kill() метод. Можно также использовать OnExited (см. here), чтобы удалить процесс, если он будет закрыт пользователем. Вы должны позвонить Close() методу Process объекту в любом случае, прежде чем удалять из списка processes и рассмотреть возможность использования CloseMainWindow() вместо метода Kill(). Вы должны просто проверить оба метода (CloseMainWindow() и Kill()) и выбрать лучшее для своего случая.

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